见过Vue的小区保安吗?

前言

业主拎着菜走到小区门口

保安A:(突然闪现)"站住!出示健康码!"

业主:"我就住3栋啊..."

保安A:"我不管!每个进小区的都得查!(掏出清单)3栋业主...嗯,你上月物业费没交!"

业主:"???我回自己家还要被拦?"

保安A:"这是规矩!要么现在缴费,要么去物业办公室(next('/property-office'))


哈哈这个保安就是路由守卫大哥,下面是一些相关的知识点!

一、路由守卫核心知识点

1. 路由守卫作用

  • 控制导航的跳转过程
  • 实现权限验证、页面拦截、数据预加载
  • 监控路由变化并执行逻辑

2. 守卫分类

graph TD A[路由守卫] --> B[全局守卫] A --> C[路由独享守卫] A --> D[组件内守卫] B --> B1[beforeEach] B --> B2[beforeResolve] B --> B3[afterEach] C --> C1[beforeEnter] D --> D1[beforeRouteEnter] D --> D2[beforeRouteUpdate] D --> D3[beforeRouteLeave]

3. 执行顺序

  1. 导航被触发
  2. 调用失活组件的 beforeRouteLeave
  3. 调用全局 beforeEach
  4. 调用路由配置的 beforeEnter
  5. 调用激活组件的 beforeRouteEnter
  6. 调用全局 beforeResolve
  7. 导航确认
  8. 调用全局 afterEach
  9. 触发 DOM 更新

二、代码示例

1. 全局守卫

javascript 复制代码
// main.js
router.beforeEach((to, from, next) => {
  // 登录验证示例
  if (to.meta.requiresAuth && !isAuthenticated()) {
    next('/login')
  } else {
    next()
  }
})
/*
作用:在路由导航之前执行,通常用于进行权限验证或登录验证。
逻辑:
to.meta.requiresAuth:检查目标路由(to)是否需要身份验证。
requiresAuth 是路由元信息(meta)中的一个字段,通常用于标记哪些路由需要登录才能访问。
isAuthenticated():检查用户是否已经登录。这是一个自定义的函数,返回 true 表示用户已登录,false 表示未登录。
如果目标路由需要登录验证且用户未登录,则通过 next('/login') 将用户重定向到登录页面。
如果不需要验证或用户已登录,则调用 next() 继续导航。
*/
router.beforeResolve((to, from, next) => {
  // 数据预加载示例
[]  preloadData(to).then(() => next())
})
/*
作用:在路由导航被确认之前执行,通常用于在路由组件被解析之前预加载数据。
逻辑:
preloadData(to):这是一个自定义的函数,用于预加载与目标路由相关的数据。它返回一个 Promise,表示数据加载的异步操作。
当数据预加载完成后,调用 next() 继续导航。
这样可以确保在路由组件被解析之前,相关数据已经准备好,提升用户体验。
*/
router.afterEach((to, from) => {
  // 页面访问统计
  trackPageView(to.path)
})
/*
作用:在路由导航完成后执行,通常用于执行一些与导航相关的后续操作,如页面访问统计。
逻辑:
trackPageView(to.path):这是一个自定义的函数,用于记录用户访问的页面路径(to.path),通常用于统计页面访问量或用户行为分析。
由于 afterEach 是在导航完成后执行的,因此它不需要调用 next()。
*/

2. 路由独享守卫

javascript 复制代码
// router.js
{
  path: '/admin',
  component: AdminPanel,
  beforeEnter: (to, from, next) => {
    if (user.role !== 'admin') {
      next('/403')
    } else {
      next()
    }
  }
}
/*
to:目标路由对象(即将进入的路由)。
from:当前路由对象(即将离开的路由)。
next:一个函数,用于控制导航行为。
*/

3. 组件内守卫

javascript 复制代码
export default {
  beforeRouteEnter(to, from, next) {
    // 无法访问组件实例
    next(vm => {
      // 通过 vm 访问组件实例
    })
  },

  beforeRouteUpdate(to, from, next) {
    // 路由参数变化时触发
    this.fetchData(to.params.id)
    next()
  },

  beforeRouteLeave(to, from, next) {
    if (this.hasUnsavedChanges) {
      const answer = confirm('有未保存的修改,确定离开吗?')
      answer ? next() : next(false)
    } else {
      next()
    }
  }
}

三、核心参数说明

参数 说明 示例用法
to 目标路由对象 to.path, to.meta
from 当前导航正要离开的路由对象 from.name
next 控制导航行为的函数 next(), next(false)

四、注意事项

  1. 必须调用 next:每个守卫都需要执行 next()
  2. 异步处理:守卫可以返回 Promise
  3. 组件实例访问
    • beforeRouteEnter 中通过回调访问实例
    • 其他组件守卫可直接使用 this
  4. 导航取消:next(false) 中断当前导航

五、典型应用场景

  1. 用户认证检查
  2. 路由权限控制
  3. 数据预加载
  4. 页面访问统计
  5. 表单未保存提示
  6. 动态设置页面标题

六、完整示例项目结构

bash 复制代码
/src
  /router
    index.js       # 路由配置
  /views
    Login.vue
    Admin.vue
    Dashboard.vue
  App.vue
  main.js

七、调试技巧

  1. 使用 console.log 跟踪守卫执行顺序
  2. Vue Devtools 查看路由状态
  3. 通过 router.onError 捕获错误
  4. 使用导航故障处理:
javascript 复制代码
router.push('/admin').catch(failure => {
  if (failure.name === 'NavigationDuplicated') {
    // 处理重复导航
  }
})

路由保安,守护你的页面平安嘻嘻!

相关推荐
爱喝水的小周8 分钟前
AJAX vs axios vs fetch
前端·javascript·ajax
Jinxiansen021111 分钟前
unplugin-vue-components 最佳实践手册
前端·javascript·vue.js
几道之旅14 分钟前
介绍electron
前端·javascript·electron
周胡杰17 分钟前
鸿蒙arkts使用关系型数据库,使用DB Browser for SQLite连接和查看数据库数据?使用TaskPool进行频繁数据库操作
前端·数据库·华为·harmonyos·鸿蒙·鸿蒙系统
315356691317 分钟前
ClipReader:一个剪贴板英语单词阅读器
前端·后端
玲小珑20 分钟前
Next.js 教程系列(十一)数据缓存策略与 Next.js 运行时
前端·next.js
qiyue7735 分钟前
AI编程专栏(三)- 实战无手写代码,Monorepo结构框架开发
前端·ai编程
断竿散人39 分钟前
JavaScript 异常捕获完全指南(下):前端框架与生产监控实战
前端·javascript·前端框架
Danny_FD41 分钟前
Vue2 + Vuex 实现页面跳转时的状态监听与处理
前端
小飞悟41 分钟前
别再只会用 px 了!移动端适配必须掌握的 CSS 单位
前端·css·设计