重识Vue路由钩子函数

路由钩子函数

全局钩子函数(导航守卫)

  • 全局前置守卫: router.beforeEach
 const router = createRouter({ ... })
 router.beforeEach((to, from, next) => {
   if (to.name !== 'Login' && !isAuthenticated) next({ name: 'Login' })
   else next()
 })
  • 全局解析守卫: router.beforeResolve
    router.beforeResolve 是获取数据或执行任何其他操作(如果用户无法进入页面时你希望避免执行的操作)的理想位置。
 router.beforeResolve(async to => {
   if (to.meta.requiresCamera) {
     try {
       await askForCameraPermission()
     } catch (error) {
       if (error instanceof NotAllowedError) {
         // ... 处理错误,然后取消导航
         return false
       } else {
         // 意料之外的错误,取消导航并把错误传给全局处理器
         throw error
       }
     }
   }
 })
  • 全局后置钩子: router.afterEach
    router.afterEach 它们对于分析、更改页面标题、声明页面等辅助功能以及许多其他事情都很有用。
 router.afterEach((to, from, failure) => {
   if (!failure) sendToAnalytics(to.fullPath)
 })

路由钩子函数(路由独享的守卫)
你可以直接在路由配置上定义 beforeEnter 守卫;
beforeEnter 守卫 只在进入路由时触发,不会在 params、query 或 hash 改变时触发;

 const routes = [
   {
     path: '/users/:id',
     component: UserDetails,
     beforeEnter: (to, from) => {
       // reject the navigation
       return false
     },
   },
 ]

你也可以将一个函数数组传递给 beforeEnter,这在为不同的路由重用守卫时很有用

 function removeQueryParams(to) {
   if (Object.keys(to.query).length)
   return { path: to.path, query: {}, hash: to.hash }
 }
 function removeHash(to) {
   if (to.hash) return { path: to.path, query: to.query, hash: '' }
 }
 const routes = [
   {
     path: '/users/:id',
     component: UserDetails,
     beforeEnter: [removeQueryParams, removeHash],
   },
   {
     path: '/about',
     component: UserDetails,
     beforeEnter: [removeQueryParams],
   },
 ]

组件钩子函数(组件内的守卫)

  • beforeRouteEnter
  • beforeRouteUpdate
  • beforeRouteLeave
const UserDetails = {
  template: `...`,
  beforeRouteEnter(to, from) {
    // 在渲染该组件的对应路由被验证前调用
    // 不能获取组件实例 `this` !
    // 因为当守卫执行时,组件实例还没被创建!
  },
  beforeRouteUpdate(to, from) {
    // 在当前路由改变,但是该组件被复用时调用
    // 举例来说,对于一个带有动态参数的路径 `/users/:id`,在 `/users/1` 和 `/users/2` 之间跳转的时候,
    // 由于会渲染同样的 `UserDetails` 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
    // 因为在这种情况发生的时候,组件已经挂载好了,导航守卫可以访问组件实例 `this`
  },
  beforeRouteLeave(to, from) {
    // 在导航离开渲染该组件的对应路由时调用
    // 与 `beforeRouteUpdate` 一样,它可以访问组件实例 `this`
  },
}

beforeRouteEnter 守卫 不能 访问 this,因为守卫在导航确认前被调用,因此即将登场的新组件还没被创建。
不过,你可以通过传一个回调给 next 来访问组件实例。在导航被确认的时候执行回调,并且把组件实例作为回调方法的参数:

beforeRouteEnter (to, from, next) {
  next(vm => {
    // 通过 `vm` 访问组件实例
  })
}
完整的导航解析流程
  1. 导航被触发。
  2. 在失活的组件里调用 beforeRouteLeave 守卫。
  3. 调用全局的 beforeEach 守卫。
  4. 在重用的组件里调用 beforeRouteUpdate 守卫。
  5. 在路由配置里调用 beforeEnter。
  6. 解析异步路由组件。
  7. 在被激活的组件里调用 beforeRouteEnter。
  8. 调用全局的 beforeResolve 守卫。
  9. 导航被确认。
  10. 调用全局的 afterEach 钩子。
  11. 触发 DOM 更新。
  12. 调用 beforeRouteEnter 守卫中传给 next 的回调函数,创建好的组件实例会作为回调函数的参数传入。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值