MST

星途 面试题库

面试题:Vue Router导航守卫在复杂权限控制场景下的设计与优化

假设你正在开发一个具有复杂权限控制的Vue应用,不同角色的用户对各个路由页面具有不同的访问权限。请详细描述你会如何利用Vue Router的导航守卫(全局守卫、路由独享守卫、组件内守卫)来设计一个灵活且高效的权限控制方案,同时要考虑如何优化该方案以提高性能,例如减少不必要的权限验证次数等。
40.3万 热度难度
前端开发Vue

知识考点

AI 面试

面试题答案

一键面试

1. 使用全局守卫实现通用权限验证

router/index.js中,通过router.beforeEach定义全局前置守卫。

import router from './router'
import store from './store'

router.beforeEach((to, from, next) => {
  const userRole = store.getters.userRole // 从vuex获取用户角色
  const requiredRoles = to.meta.roles // 获取路由元信息中的所需角色
  if (requiredRoles) {
    if (requiredRoles.includes(userRole)) {
      next()
    } else {
      next({ name: 'noPermission' }) // 跳转到无权限页面
    }
  } else {
    next() // 无需特定角色,直接放行
  }
})

2. 路由独享守卫处理特定路由权限

在定义路由时,可以使用beforeEnter来设置路由独享守卫。

const routes = [
  {
    path: '/admin',
    name: 'admin',
    component: () => import('@/views/Admin.vue'),
    beforeEnter: (to, from, next) => {
      const userRole = store.getters.userRole
      if (userRole === 'admin') {
        next()
      } else {
        next({ name: 'noPermission' })
      }
    }
  }
]

3. 组件内守卫在组件级别进行权限验证

在组件内部,可以使用beforeRouteEnterbeforeRouteUpdatebeforeRouteLeave守卫。例如,在某个组件中:

export default {
  name: 'SomeComponent',
  beforeRouteEnter (to, from, next) {
    const userRole = this.$store.getters.userRole
    const requiredRole = to.meta.role
    if (requiredRole && requiredRole === userRole) {
      next()
    } else {
      next({ name: 'noPermission' })
    }
  }
}

4. 性能优化

  • 缓存用户权限:将用户权限信息缓存到本地存储(如localStorage)或Vuex中,减少每次验证都从服务器获取权限数据的开销。
  • 减少不必要验证:对于已经验证通过的用户,在其会话期间不再重复验证相同的权限。可以在全局守卫中记录已验证的路由,下次访问相同路由时跳过验证。例如,在全局守卫中添加一个变量记录已验证路由:
let verifiedRoutes = []
router.beforeEach((to, from, next) => {
  if (verifiedRoutes.includes(to.path)) {
    next()
    return
  }
  const userRole = store.getters.userRole
  const requiredRoles = to.meta.roles
  if (requiredRoles) {
    if (requiredRoles.includes(userRole)) {
      verifiedRoutes.push(to.path)
      next()
    } else {
      next({ name: 'noPermission' })
    }
  } else {
    verifiedRoutes.push(to.path)
    next()
  }
})
  • 延迟加载权限数据:在应用启动时,只加载必要的基本权限数据,当用户访问需要特定权限的页面时,再按需加载详细的权限数据。