跳转到内容
主菜单
主菜单
移至侧栏
隐藏
导航
首页
最近更改
随机页面
MediaWiki帮助
代码酷
搜索
搜索
中文(中国大陆)
外观
创建账号
登录
个人工具
创建账号
登录
未登录编辑者的页面
了解详情
贡献
讨论
编辑“︁
Vue Router导航守卫
”︁
页面
讨论
大陆简体
阅读
编辑
编辑源代码
查看历史
工具
工具
移至侧栏
隐藏
操作
阅读
编辑
编辑源代码
查看历史
常规
链入页面
相关更改
特殊页面
页面信息
外观
移至侧栏
隐藏
您的更改会在有权核准的用户核准后向读者展示。
警告:
您没有登录。如果您进行任何编辑,您的IP地址会公开展示。如果您
登录
或
创建账号
,您的编辑会以您的用户名署名,此外还有其他益处。
反垃圾检查。
不要
加入这个!
{{DISPLAYTITLE:Vue Router导航守卫}} '''Vue Router导航守卫'''是Vue Router提供的一种机制,允许开发者通过钩子函数在路由导航过程中进行拦截和控制。这些守卫可以用于权限验证、页面访问控制、数据预加载等场景,为单页应用(SPA)提供了更精细的路由控制能力。 == 导航守卫概述 == 导航守卫分为三类,按触发顺序排列如下: 1. '''全局守卫''':作用于所有路由 2. '''路由独享守卫''':只作用于特定路由 3. '''组件内守卫''':在路由组件内定义 导航解析流程可以用以下mermaid图表示: <mermaid> flowchart LR A[导航触发] --> B[调用离开守卫] B --> C[调用全局前置守卫] C --> D[调用路由独享守卫] D --> E[调用组件内守卫] E --> F[确认导航] F --> G[调用全局后置钩子] </mermaid> == 全局守卫 == 全局守卫通过router实例直接注册,包含以下三种: === beforeEach === 在导航触发前调用,常用于权限验证。 <syntaxhighlight lang="javascript"> router.beforeEach((to, from, next) => { // to: 即将进入的目标路由 // from: 当前导航正要离开的路由 // next: 必须调用此函数来resolve这个钩子 if (to.meta.requiresAuth && !isAuthenticated()) { next('/login') } else { next() // 继续导航 } }) </syntaxhighlight> === beforeResolve === 在导航被确认前调用,适合确保异步操作完成。 <syntaxhighlight lang="javascript"> router.beforeResolve(async to => { if (to.meta.fetchData) { await fetchDataBeforeEnter(to.params.id) } }) </syntaxhighlight> === afterEach === 导航完成后调用,没有next参数。 <syntaxhighlight lang="javascript"> router.afterEach((to, from) => { logNavigation(to.path, from.path) }) </syntaxhighlight> == 路由独享守卫 == 直接在路由配置中定义: <syntaxhighlight lang="javascript"> const routes = [ { path: '/admin', component: AdminPanel, beforeEnter: (to, from, next) => { if (user.role !== 'admin') { next('/forbidden') } else { next() } } } ] </syntaxhighlight> == 组件内守卫 == 在路由组件内定义: === beforeRouteEnter === 在渲染该组件的对应路由被确认前调用,不能访问组件实例(this)。 <syntaxhighlight lang="javascript"> beforeRouteEnter(to, from, next) { next(vm => { // 通过vm访问组件实例 vm.loadData(to.params.id) }) } </syntaxhighlight> === beforeRouteUpdate === 在当前路由改变但组件被复用时调用。 <syntaxhighlight lang="javascript"> beforeRouteUpdate(to, from, next) { this.userId = to.params.id this.fetchUserData() next() } </syntaxhighlight> === beforeRouteLeave === 在导航离开该组件的对应路由时调用。 <syntaxhighlight lang="javascript"> beforeRouteLeave(to, from, next) { if (this.unsavedChanges) { if (confirm('有未保存的更改,确定离开?')) { next() } else { next(false) } } else { next() } } </syntaxhighlight> == 完整导航解析流程 == 1. 导航被触发 2. 调用即将离开组件的beforeRouteLeave 3. 调用全局的beforeEach 4. 在重用的组件里调用beforeRouteUpdate 5. 调用路由配置里的beforeEnter 6. 解析异步路由组件 7. 调用即将进入组件的beforeRouteEnter 8. 调用全局的beforeResolve 9. 导航被确认 10. 调用全局的afterEach 11. 触发DOM更新 12. 执行beforeRouteEnter中传给next的回调函数 == 实际应用案例 == === 案例1:权限控制 === <syntaxhighlight lang="javascript"> router.beforeEach((to, from, next) => { const publicPages = ['/login', '/register'] const authRequired = !publicPages.includes(to.path) const loggedIn = localStorage.getItem('user') if (authRequired && !loggedIn) { return next('/login') } next() }) </syntaxhighlight> === 案例2:页面访问统计 === <syntaxhighlight lang="javascript"> router.afterEach((to, from) => { analytics.trackPageView(to.path) }) </syntaxhighlight> === 案例3:动态标题 === <syntaxhighlight lang="javascript"> router.beforeEach((to, from, next) => { document.title = to.meta.title || '默认标题' next() }) </syntaxhighlight> == 数学公式示例 == 如果需要计算导航耗时,可以使用以下公式: <math> T_{nav} = T_{beforeEach} + T_{beforeEnter} + T_{beforeRouteEnter} + T_{render} </math> 其中: * <math>T_{beforeEach}</math> 是全局前置守卫执行时间 * <math>T_{beforeEnter}</math> 是路由独享守卫执行时间 * <math>T_{beforeRouteEnter}</math> 是组件内守卫执行时间 * <math>T_{render}</math> 是组件渲染时间 == 注意事项 == 1. 确保总是调用next(),否则钩子不会resolved 2. 在beforeRouteEnter中无法访问this,因为组件实例还未创建 3. 导航守卫是异步执行的 4. 可以使用next(false)中止当前导航 5. 可以使用next('/path')或next({ path: '/path' })重定向 通过合理使用导航守卫,开发者可以构建更安全、更高效的单页应用,实现复杂的路由控制逻辑。 [[Category:前端框架]] [[Category:Vue.js]] [[Category:Vue Router路由]]
摘要:
请注意,所有对代码酷的贡献均被视为依照知识共享署名-非商业性使用-相同方式共享发表(详情请见
代码酷:著作权
)。如果您不希望您的文字作品被随意编辑和分发传播,请不要在此提交。
您同时也向我们承诺,您提交的内容为您自己所创作,或是复制自公共领域或类似自由来源。
未经许可,请勿提交受著作权保护的作品!
取消
编辑帮助
(在新窗口中打开)