Vue 导航控制与守卫:全方位路由管控指南

导航守卫分类与实战

导航守卫是 Vue Router 的核心控制机制,允许开发者在路由切换的不同阶段插入逻辑处理。

全局守卫:应用级管控

// 全局前置守卫
router.beforeEach((to, from, next) => {
  console.log(`全局拦截:从 ${from.path} 到 ${to.path}`)
  next() // 必须调用
})

// 全局后置钩子
router.afterEach((to, from) => {
  document.title = to.meta.title || '默认标题'
})

实践建议

  • 适合全局权限检查、埋点统计等通用逻辑
  • beforeEach 必须调用 next(),否则路由会挂起
  • afterEach 没有 next 参数,适合无阻塞操作

路由独享守卫:精细化控制

const routes = [
  {
    path: '/admin',
    component: AdminPanel,
    beforeEnter: (to, from, next) => {
      if (!localStorage.getItem('adminToken')) {
        next('/login')
      } else {
        next()
      }
    }
  }
]

实践建议

  • 适用于特定路由的权限校验
  • 比全局守卫更早执行,可减少不必要的全局检查

组件内守卫:组件级管控

export default {
  beforeRouteEnter(to, from, next) {
    // 不能访问 this(组件未创建)
    next(vm => {
      // 通过 vm 访问组件实例
    })
  },
  
  beforeRouteUpdate(to, from, next) {
    // 相同组件但路由变化时触发
    this.fetchData(to.params.id)
    next()
  },
  
  beforeRouteLeave(to, from, next) {
    if (this.hasUnsavedChanges) {
      if (!confirm('离开将丢失未保存数据')) {
        return next(false)
      }
    }
    next()
  }
}

执行顺序

图1

导航行为控制技巧

取消导航

next(false) // 中断当前导航,保持原路由

使用场景

  • 表单未保存提示
  • 权限校验未通过

重定向控制

// 绝对路径重定向
next('/login')

// 相对位置重定向
next({ path: 'approve' })

// 带参数重定向
next({
  name: 'user',
  params: { id: 123 }
})

错误处理

next(new Error('网络超时')) // 触发 router.onError

// 全局错误捕获
router.onError(error => {
  console.error('路由错误:', error)
  alert('页面加载失败,请刷新重试')
})

最佳实践总结

  1. 权限控制组合拳

    // 全局检查登录态
    router.beforeEach(async (to) => {
      if (to.meta.requiresAuth && !await store.checkAuth()) {
        return { path: '/login', query: { redirect: to.fullPath } }
      }
    })
    
    // 路由级检查具体权限
    {
      path: '/admin',
      beforeEnter: checkAdminRole
    }
    
    // 组件级补充校验
    beforeRouteEnter(to, from, next) {
      if (!to.meta.accessibleFeatures.includes('export')) {
        next('/unauthorized')
      }
    }
  2. 数据预加载模式

    beforeRouteEnter(to, from, next) {
      api.fetchDetail(to.params.id).then(data => {
        next(vm => vm.setData(data))
      })
    }
  3. 离开守卫优化

    beforeRouteLeave(to, from, next) {
      if (this.isSaving) {
        return next(false)
      }
      // 异步确认
      return this.confirmSave().then(next).catch(() => next(false))
    }

通过合理组合不同层级的导航守卫,可以实现从粗粒度到细粒度的完整路由管控体系,满足各类复杂业务场景的需求。

评论已关闭