MST

星途 面试题库

面试题:Vue Router嵌套路由下的导航守卫优化与异常处理

在一个多层嵌套路由的Vue项目中,例如'/admin/dashboard/user/:userId',在进入该路由前需要进行权限验证,在离开该路由时需要保存用户操作记录。请详细阐述如何合理使用全局导航守卫、路由独享守卫和组件内导航守卫来实现这些功能,并且在权限验证失败或操作记录保存失败时如何进行友好的异常处理,包括页面提示和路由跳转等。同时,分析在不同场景下使用不同类型导航守卫的优缺点。
32.2万 热度难度
前端开发Vue

知识考点

AI 面试

面试题答案

一键面试

实现权限验证和操作记录保存的方法

  1. 全局导航守卫:可以在router.js文件中使用router.beforeEach来进行全局的权限验证。这样在每次路由切换前都会执行权限验证逻辑。
import router from './router'
import store from './store'

router.beforeEach((to, from, next) => {
  const hasPermission = store.getters.hasPermission // 假设从vuex获取权限信息
  if (to.matched.some(record => record.meta.requiresAuth)) {
    if (hasPermission) {
      next()
    } else {
      next({ name: 'Login' }) // 跳转到登录页
    }
  } else {
    next()
  }
})

优点:全局统一处理,代码集中,便于维护和管理所有路由的权限验证逻辑。 缺点:如果逻辑复杂,会导致beforeEach函数变得臃肿,难以维护。对于特定路由的特殊处理不够灵活。

  1. 路由独享守卫:在定义路由时,可以在单个路由配置中使用beforeEnter来进行权限验证。例如:
const routes = [
  {
    path: '/admin/dashboard/user/:userId',
    name: 'UserDetail',
    component: UserDetail,
    beforeEnter: (to, from, next) => {
      const hasPermission = store.getters.hasPermission
      if (hasPermission) {
        next()
      } else {
        next({ name: 'Login' })
      }
    }
  }
]

优点:针对单个路由进行定制化的守卫处理,逻辑清晰,不影响其他路由。 缺点:如果有多个路由需要相同的权限验证逻辑,会导致代码重复。

  1. 组件内导航守卫:在组件内部使用beforeRouteEnter进行进入路由前的权限验证,使用beforeRouteLeave保存用户操作记录。例如:
export default {
  name: 'UserDetail',
  data() {
    return {
      // 组件数据
    }
  },
  beforeRouteEnter(to, from, next) {
    const hasPermission = this.$store.getters.hasPermission
    if (hasPermission) {
      next()
    } else {
      next({ name: 'Login' })
    }
  },
  beforeRouteLeave(to, from, next) {
    const saveResult = this.$store.dispatch('saveUserOperation', {
      operation: 'leave UserDetail',
      userId: this.$route.params.userId
    })
    if (saveResult) {
      next()
    } else {
      this.$message.error('操作记录保存失败')
      next(false)
    }
  }
}

优点:与组件紧密结合,方便访问组件内的数据和方法。对于当前组件相关的操作处理非常方便。 缺点:逻辑分散在各个组件中,不利于整体的统一管理和维护。

异常处理

  1. 权限验证失败
    • 页面提示:可以使用UI库的提示组件,如Element UI的$message来显示提示信息,例如this.$message.error('权限不足,请登录')
    • 路由跳转:跳转到登录页面,如next({ name: 'Login' })
  2. 操作记录保存失败
    • 页面提示:同样使用提示组件,如this.$message.error('操作记录保存失败')
    • 路由处理:可以阻止离开当前路由,如next(false),让用户知道操作记录未保存成功。也可以根据业务需求,在提示后继续跳转,如next()