You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VueJS项目中如何限制X角色仅可访问指定个人详情页面

实现方案

你可以通过动态路由重定向+全局路由守卫组合实现需求,具体步骤如下:


1. 修改路由配置

首先把根路径的写死重定向改成动态逻辑,同时给路由添加meta字段标记权限要求:

const routes = [
  {
    path: '/',
    name: 'Home',
    component: Dashboard,
    // 改成函数式动态重定向
    redirect: to => {
      const user = localStorage.getItem('user') ? JSON.parse(localStorage.getItem('user')) : null
      // 若用户信息已初始化完成,也可直接从store中取值判断
      if (user?.is_X) {
        return `/streamers/${user.id}/detail/`
      }
      return '/streamers/'
    },
    children:[
      {
        path: 'streamers/',
        name: 'Streamers',
        component: Streamers,
        meta: {
          // 标记该路由禁止X角色访问
          forbidX: true
        }
      },
      {
        path: 'streamers/:id/detail/',
        name: 'StreamerDetail',
        component: StreamerDetail,
        meta: {
          // 标记需要登录才能访问
          requireAuth: true
        }
      },
    ],
  },
  {
    path: '/login',
    name: 'Login',
    component: Login,
  }
]

2. 添加全局路由守卫

在你的router/index.js文件中创建路由实例后,添加前置守卫做权限校验:

const router = createRouter({ routes })

router.beforeEach((to, from, next) => {
  // 登录页直接放行
  if (to.name === 'Login') return next()
  
  // 未登录统一跳转到登录页
  if (!store.getters.isAuthenticated) return next({ name: 'Login' })

  const isX = store.state.auth.user?.is_X
  const currentUserId = store.state.auth.user?.id

  // 校验X角色禁止访问的路由
  if (isX && to.meta.forbidX) {
    // 直接跳转到X角色自己的详情页
    return next({ name: 'StreamerDetail', params: { id: currentUserId } })
  }

  // 校验X角色只能访问自己的详情页
  if (isX && to.name === 'StreamerDetail') {
    if (to.params.id !== String(currentUserId)) {
      // 访问其他人的详情页时,跳回自己的详情页或者自定义403页
      return next({ name: 'StreamerDetail', params: { id: currentUserId } })
    }
  }

  next()
})

3. 调整Dashboard组件的异步逻辑

因为用户信息加载是异步操作,需要确保路由守卫执行时用户信息已经初始化,所以修改Dashboard的mounted逻辑为异步等待:

export default {
  name: "Dashboard.vue",
  data() {
    return {
      snackbar: {
        color: null,
        message: null,
      },
      userLoaded: false
    }
  },
  async mounted(){
    // 等待cookie校验和token刷新完成
    await this.$store.dispatch('checkCookiesOnInit')
    if (!this.$store.getters.isAuthenticated){
      await this.$store.dispatch('refreshToken')
    }
    this.userLoaded = true
    // 用户信息加载完成后如果是X角色,主动跳转一次避免初始化时重定向失效
    if (this.$store.state.auth.user?.is_X && this.$route.name === 'Streamers') {
      this.$router.push({
        name: 'StreamerDetail',
        params: { id: this.$store.state.auth.user.id }
      })
    }
  },
}

同时修改模板,用户信息加载完成前可以加loading避免闪屏:

<template>
   <div v-if="$store.getters.isAuthenticated && userLoaded">
....
   </div>
   <div v-else>加载中...</div>
</template>

补充说明

如果你的项目中用户信息是在refreshToken执行完成后才写入store,建议在路由守卫中加个等待逻辑,避免守卫执行时用户信息还没加载完成导致判断错误。

内容的提问来源于stack exchange,提问作者Milano

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 21:36:03