• vue-router4之导航守卫


    专栏目录请点击

    全局守卫

    前置守卫

    const router = createRouter({ ... })
    
    router.beforeEach((to, from) => {
      // ...
      // 返回 false 以取消导航
      return false
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    参数

    • to即将要进入的目标
    • from当前导航正要离开的路由
    • next表示路由是否要放行,他是一个函数,里面可以跟一个对象,对象中是重定向的路由,每次导航需要注意的是,next只能调用一次

    返回值

    • false 表示取消导航,不跳转
    • 一个路由地址,效果和router.push相同
    • true或者undefined,直接导航到to所在的路由

    错误抓取

    当路由跳转出现任何错误的时候,都会调用onError事件 点击

    解析守卫

    调用时机:导航被确认之前,同时在所有组件内守卫和异步路由组件被解析之后,解析守卫就被正确调用。

    router.beforeResolve(async to => {
      if (to.meta.requiresCamera) {
        try {
          await askForCameraPermission()
        } catch (error) {
          if (error instanceof NotAllowedError) {
            // ... 处理错误,然后取消导航
            return false
          } else {
            // 意料之外的错误,取消导航并把错误传给全局处理器
            throw error
          }
        }
      }
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    后置钩子

    • 后置钩子不会接受next函数,也不会改变到行本身
    • 一般用于它们对于分析、更改页面标题、声明页面等辅助功能
    router.afterEach((to, from, failure) => {
      if (!failure) sendToAnalytics(to.fullPath)
    })
    
    • 1
    • 2
    • 3

    单个路由

    路由守卫只会在进入路由的时候触发,不会在其参数,如 paramsqueryhash改变的时候触发

    路由独享守卫

    函数

    const routes = [
      {
        path: '/users/:id',
        component: UserDetails,
        beforeEnter: (to, from) => {
          // reject the navigation
          return false
        },
      },
    ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    数组

    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],
      },
    ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    组件级

    • beforeRouteEnter:不可以访问this,因为守卫在导航确认前被调用,因此即将登场的新组件还没被创建。
    • 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`
      },
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    对于beforeRouteEnter我们可以传递一个回调来访问组件的实例

    beforeRouteEnter (to, from, next) {
      next(vm => {
        // 通过 `vm` 访问组件实例
      })
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    离开守卫,我们一般用于做某些验证,返回false来取消跳转

    beforeRouteLeave (to, from) {
      const answer = window.confirm('Do you really want to leave? you have unsaved changes!')
      if (!answer) return false
    }
    
    • 1
    • 2
    • 3
    • 4

    组合式api

    • onBeforeRouteUpdate
    • onBeforeRouteLeave 点击

    完整的导航解析流程

    1. 导航被触发。
    2. 在失活的组件里调用 beforeRouteLeave 守卫。
    3. 调用全局的 beforeEach 守卫。
    4. 在重用的组件里调用 beforeRouteUpdate 守卫(2.2+)。
    5. 在路由配置里调用 beforeEnter
    6. 解析异步路由组件。
    7. 在被激活的组件里调用 beforeRouteEnter
    8. 调用全局的 beforeResolve 守卫(2.5+)。
    9. 导航被确认。
    10. 调用全局的 afterEach 钩子。
    11. 触发 DOM 更新。
    12. 调用 beforeRouteEnter 守卫中传给 next 的回调函数,创建好的组件实例会作为回调函数的参数传入。
  • 相关阅读:
    使用分类权重解决数据不平衡的问题
    systemverilog学习 --- 代码重用
    Java实现图片和Base64之间的相互转化
    数据抓取使用爬虫ip常见问题解决方法
    瑞吉外卖强化(二):数据库优化
    最新版本 Stable Diffusion 开源 AI 绘画工具之汉化篇
    【HCIP-WLAN V2.0 正式发布!】
    Android7.1.1系统,Toast的Exception: android.view.WindowManager$BadTokenException解决
    uniapp vue3.0+TS 上传单张或多张图片,并且能删除和预览。
    【软件工程导论】1.软件过程模型
  • 原文地址:https://blog.csdn.net/youhebuke225/article/details/125495813