vue的路由守卫

vue的路由守卫,也叫路由钩子、导航守卫或导航钩子。路由(vue-router) 提供的导航守卫主要用来:通过跳转或取消的方式守卫导航。有多种机会植入路由导航过程中:全局的,单个路由独享的, 或者组件级的。

注意:参数或查询的改变并不会触发进入/离开的导航守卫。

1.全局路由守卫

  • 全局前置守卫

使用router.beforeEach注册全局的前置路由守卫。

// index.js
const router=new VueRouter({...})
router.beforeEach((to,from,next)=>{
    //...
})

当一个导航触发时,全局前置守卫按照创建顺序调用。守卫是异步解析执行,此时导航在所有守卫 resolve 完之前一直处于等待中。
方法接收三个参数:
to: Route ,即将要进入的目标 路由对象
from: Route,当前导航正要离开的路由
next: Function,一定要调用该方法来resolve这个钩子。执行效果依赖 next 方法的调用参数。
next():进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是confirmed (确认的)。
next(false): 中断当前的导航。如果浏览器的 URL 改变了 (可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到 from 路由对应的地址。
next('/') 或者 next({ path: '/' }):跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。你可以向 next 传递任意位置对象,且允许设置诸如 replace: true、name: 'home' 之类的选项以及任何用在router-link的 to prop或 router.push中的选项。
next(error):(2.4.0+) 如果传入 next 的参数是一个 Error 实例,则导航会被终止且该错误会被传递给 router.onError()注册过的回调。
确保要调用 next方法,否则钩子就不会被 resolved。

  • 全局后置守卫

使用router.afterEach注册全局的后置守卫。

//index.js
const router=new VueRouter({...})
router.afterEach((to,from)=>{
    //...
})

不同于前置守卫的是,后置守卫没有next 函数,也不会改变导航本身。

  • 全局解析守卫

这个是vue2.5.0版本新增的。使用router.beforeReslolve注册全局的解析守卫。

//index.js
const router=new VueRouter({...})
router.beforeReslolve((to,from,next)=>{
    //...
})

这和 router.beforeEach 类似,区别在于:在导航被确认之前,同时在所有组件内守卫和异步路由组件被解析之后,解析守卫就被调用。

2.路由独享的守卫

顾名思义,即单个路由独享的导航钩子,使用boforeEnter在路由配置上直接进行注册。

// router.js
const router=new VueRouter({
    routes:[
        {
            path:'/login',
            name:'login',
            component:()=>import('@/components/Login/Login'),
            beforeEnter: (to,from,next) => {
                // ...
            }
        }
    ]
})

使用方法与全局守卫相同,不同点在于:全局守卫可以作用于全局,路由独享守卫只作用于被设置守卫的路由。

3.组件级的守卫

组件内的守卫分为beforeRouteEnterbeforeRouterUpdatebeforeRouteLeave

  • beforeRouteEnter

在渲染该组件的对应路由被 confirm 前调用。

<script>
export default{
    data(){
        return{
            
        }
    },
    beforeRouteEnter:(to,from,next) => {
        // ...
    },
}
</script>

注意:beforeRouteEnter 不能获取组件实例 this,因为当守卫执行前,组件实例被没有被创建出来,剩下两个钩子则可以正常获取组件实例 this。

但是并不意味着在 beforeRouteEnter 中无法访问组件实例,我们可以通过给 next 传入一个回调来访问组件实例。在导航被确认时,会执行这个回调,这时就可以访问组件实例了。

<script>
export default{
    data(){
        return{
            name:'MM'
        }
    },
    beforeRouteEnter:(to,from,next) => {
        next(vm=>{
            console.log("hello,"+vm.name)  //hello,MM
        })
    },
}
</script>

注意:仅仅是 beforRouteEnter 支持给 next 传递回调,其他两个并不支持。因为归根结底,支持回调是为了解决 this 问题,而其他两个钩子的 this 可以正确访问到组件实例,所有没有必要使用回调。

  • beforeRouteUpdate

这个方法是vue-router2.2版本加上的。因为原来的版本中,如果一个在两个子路由之间跳转,是不触发beforeRouteLeave的。这会导致某些重置操作,没地方触发。在之前,我们都是用watch 的。但是通过这个钩子,我们有了更好的方式。

<script>
export default{
    data(){
        return{
            
        }
    },
    beforeRouteUpdate:(to,from,next) => {
        // ...
    },
}
</script>
  • beforeRouteLeave

这个离开守卫通常用来禁止用户在还未保存修改前突然离开。该导航可以通过 next(false) 来取消。

<script>
export default{
    data(){
        return{
            
        }
    },
    beforeRouteLeave:(to,from,next) => {
        // ...
    },
}
</script>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容