Vue Router 3.x 导航守卫基础概念理解

Vue Router 导航守卫(点击查看文章目录)→

导航:表示路由正在发生改变,进行路由跳转
守卫:古代的守门的士兵'守卫',守卫可以通过条件判断路由能不能进行跳转。

 

三大守卫: 全局守卫,路由独享守卫,组件内守卫。

注意从官网上可知,Vue Router 4.X的版本有不同,next变为可选参数?还没学习到暂时不作讨论,该文章全部为Vue Router 3.x版本的。

1.全局守卫:

项目当中任何路由变化都可以检测到,通过条件判断可不可以进行路由跳转。
举例子:紫禁城【皇帝、太后、妃子】,紫禁城大门守卫全要排查

 

前置守卫:          路由跳转之前可以做一些事情。
后置守卫:          路由跳转已经完成在执行。
全局解析守卫:   和 router.beforeEach 类似,区别是在导航被确认之前,同时在所有组件内守卫和异步路由组件被解析之后,解析守卫就被调用。(不理解区别)
全局前置守卫:   在路由跳转完毕之后才会执行一次
全局后置钩子:   不接受第三个参数next,也不会改变导航本身
const router = new VueRouter({ ... })

router.beforeEach((to, from, next) => {
  // ...
})
   
  •     守卫里的三个参数

 to:                  要跳转到哪个路由(路径)
    from:             从哪个路由来的(路径)
    next:             放行函数     next()代表放行     next('/path') 或者 next({path:' '})   放行到指定路由        
    next(false):中断当前的导航,意思是

确保 next 函数在任何给定的导航守卫中都被严格调用一次。它可以出现多于一次,但是只能在所有的逻辑路径都不重叠的情况下,否则钩子永远都不会被解析或报错

解释:每个导航守卫必须调用next函数一次保证放行。什么时候会出现多次next函数?在路径判断(意味着在不同路径里写响应逻辑),可以出现多次。如果同一路径里调用多次next,这是糟糕的写法会报错或者会无法实现想要的功能。

  •    应用场景

前置守卫,很好理解,登录验证控制页面的跳转及重定向。以下是实际业务中验证登录判断路由跳转及重定向。

    // 用户登录了才会有token,未登录或者退出登录都没有token
    let token = store.state.userStore.token
    // 用户信息
    let name  = store.state.userStore.userInfo.name
    // 已经登录
    if(token){
        if (to.path=='/login'||to.path=='/register') {
            // 用户已经登录了还想去login,不能去,停留在首页
            next('/home')
        }else{
            // 登录,去的不是login
            // 如果用户名已有不拦
            if (name) {
                next()
            }else{
                // 没有用户信息,派发actions,让仓库存储用户信息在跳转
                try {
                    // 获取用户信息成功放行
                    await store.dispatch('userStore/userInfo')
                    next()
                } catch (error) {
                    // token失效了
                    // 清除token失效token
                    await store.dispatch('userStore/quitRegister')
                    // 跳转登录界面,让用户重新登录.  ******这里应该是跳转登录界面而不是放行登录界面
                    next('/login')
                }
            }
        }
    }else{
        // 未登录:不能去交易相关:不能去支付相关【pay,paysuccess】,不能去个人中心
        // 未登录去上面这些路由 ----强制登录
        let toPath = to.path
        if(toPath.indexOf('/trade')!=-1 || toPath.indexOf('/pay')!=-1 || toPath.indexOf('/center')!=-1){
            // 把未登录的时候想去而没有去成的路径信息,存储于地址栏中【路由】
            next('/login?redirect='+toPath);
        }else{
        // 未登录去这些路由(home|search|shopcart) ----放行
            next()    
        }
    }

 

后置钩子,就是对跳转后的页面进行例如滚动条回调0 0 位置、更新页面title、懒加载结束等等。

router.afterEach((to, from) => {
    setTitle(to, router.app)
    iView.LoadingBar.finish()
    window.scrollTo(0, 0)
})

 

 

2.路由独享守卫:

【通过什么条件能判断用户登录、未登录】针对某一个路由的守卫

举例子:紫禁城【皇帝、太后、妃子】,是去相应的【皇帝、太子、妃子】寝宫 的路上守卫

用法和全局前置守卫类似,直接使用在路由配置中。

    {   
        name:'pay',
        path:'/pay',
        component:()=>import('@/pages/Pay'),
        meta:{showFooter:true},
        // 路由独享守卫
        beforeEnter: (to, from, next) => {
            // ...
            if (from.path =='/trade') {
                next()
            }else{
                next(false)
            }
        }
    },

 

 

3.组件内守卫:

也是负责某一个路由守卫,直接写在组件内!
举例子:已经到了皇帝寝室外面,是专门负责的守卫
beforeRouteEnter():    进入该组件路由前 。验证登录判断
beforeRouteUpdate(): 路由更新钩子函数。路由地址没有变化,意味着组件化复用,但是参数变了,如search搜索页面。
beforeRouteLeave():   离开该组件路由后。这个离开守卫通常用来禁止用户在还未保存修改前突然离开。该导航可以通过 next(false) 来取消。
    // 组件内守卫,有三个
    beforeRouteEnter(to, from, next) {
      // 在渲染该组件的对应路由被 confirm 前调用
      // 不!能!获取组件实例 `this`
      // 因为当守卫执行前,组件实例还没被创建
      if (from.path =='/pay') {
        next()
      }else{
        next(false)
      }
    },
    beforeRouteUpdate(to, from, next) {
      // 在当前路由改变,但是该组件被复用时调用
      // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
      // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
      // 可以访问组件实例 `this`
    },
    beforeRouteLeave(to, from, next) {
      // 导航离开该组件的对应路由时调用
      // 可以访问组件实例 `this`
    }

 

路由设置

 路由模式,滚动行为
let router = new VueRouter({
    mode:'hash',
    // 配置路由,kv一致省略v
    routes,
    // 滚动行为
    scrollBehavior (to, from, savedPosition) {
        // return 期望滚动到哪个的位置
        // 返回到y=0,滚动条在最上方
        return { y: 0 }
    }
})

 

完整的导航解析流程

  1. 导航被触发。
  2. 在失活的组件里调用 beforeRouteLeave 守卫。
  3. 调用全局的 beforeEach 守卫。
  4. 在重用的组件里调用 beforeRouteUpdate 守卫 (2.2+)。
  5. 在路由配置里调用 beforeEnter
  6. 解析异步路由组件。
  7. 在被激活的组件里调用 beforeRouteEnter
  8. 调用全局的 beforeResolve 守卫 (2.5+)。
  9. 导航被确认。
  10. 调用全局的 afterEach 钩子。
  11. 触发 DOM 更新。调用 beforeRouteEnter 守卫中传给 next 的回调函数,创建好的组件实例会作为回调函数的参数传入。
posted @ 2022-02-15 11:21  wanglei1900  阅读(505)  评论(0编辑  收藏  举报