2024-03-16 16:39:06
Vue.js 中路由守卫的核心作用是通过控制导航流程实现权限验证、数据预加载和日志记录等功能,其实现方式包括全局守卫、路由独享守卫和组件内守卫三种类型。
一、使用场景全局前置守卫(beforeEach)在每次路由导航前触发,常用于权限验证。
router.beforeEach((to, from, next) => { if (to.meta.requiresAuth && !isAuthenticated()) { next({ path: '/login', query: { redirect: to.fullPath } }); } else { next(); }});关键点:通过 to.meta 读取路由元信息,next() 必须调用以继续导航。
全局解析守卫(beforeResolve)在所有组件内守卫和异步路由组件解析后触发,适合数据预加载。
router.beforeResolve(async (to, from, next) => { if (to.name === 'UserDetails') { try { await store.dispatch('fetchUser', to.params.id); next(); } catch { next({ name: 'NotFound' }); } } else { next(); }});关键点:支持异步操作,需处理成功/失败场景。
全局后置钩子(afterEach)导航完成后触发,用于日志记录或页面标题更新。
router.afterEach((to, from) => { console.log(`Navigated from ${from.path} to ${to.path}`);});在路由配置中直接定义,仅对特定路由生效。
{ path: '/admin', component: Admin, beforeEnter: (to, from, next) => { if (!isAdmin()) next('/forbidden'); else next(); }}beforeRouteEnter在组件渲染前触发,无法访问 this,但可通过 next(vm => {...}) 访问组件实例。
beforeRouteEnter(to, from, next) { fetchData().then(data => { next(vm => vm.setData(data)); });}beforeRouteUpdate在当前路由复用时触发(如动态参数变化)。
beforeRouteUpdate(to, from, next) { if (to.params.id !== from.params.id) { this.loadData(to.params.id); } next();}beforeRouteLeave在离开组件时触发,常用于表单未保存提醒。
beforeRouteLeave(to, from, next) { if (this.formIsDirty) { if (confirm('Discard changes?')) next(); else next(false); // 取消导航 } else { next(); }}调用离开组件的 beforeRouteLeave。
调用全局前置守卫 beforeEach。
调用路由独享守卫 beforeEnter。
解析异步路由组件(如动态导入)。
调用全局解析守卫 beforeResolve。
调用进入组件的 beforeRouteEnter。
导航完成,触发 afterEach。
在守卫中添加 console.log 跟踪执行流程。
使用浏览器开发者工具的 Sources 面板设置断点。
通过合理使用路由守卫,可以显著提升 Vue.js 应用的安全性、用户体验和可维护性。