vue-router提供了导航守卫功能,其中包括全局导航守卫、路由独享导航守卫和组件内守卫三种。这里我们主要谈谈组件内守卫的相关内容。

1.组件内守卫书写与分类

组件内守卫在路由组件内部直接定义即可。
其中包括三种守卫:

前置守卫:beforeRouteEnter
更新守卫:beforeRouteUpdate
后置守卫:beforeRouteLeave
...

<script>
export default {
    data(){
        ...
    },
    methods: {
        ...
    },
    ...
    beforeRouteEnter(to, from, next){
        ...
    },
    beforeRouteUpdate(to, from, next){
        ...
    },
    beforeRouteLeave(to, from, next){
        ...
    }
}
</script>

...

守卫的三个参数:
to:Route对象实例,路由即将进入的目标。
from:Route对象实例,当前即将离开的路由对象。
next:Function,用来resolve守卫,效果根据传参不同而不同。

  • 无参数:直接执行管道内下一个守卫;
  • false:中断导航,如果URL已经发生变化,则重置为from的URL;
  • URL:跳转到新的路由;
  • Error对象实例:终止导航,并将错误传递给router.onError()中注册的回调;
  • Function:回调函数,仅在前置守卫支持回调函数。

2. 前置守卫

由于在执行守卫之前,组件实例还未创建,因此在该守卫中,不能够使用this来获取组件实例。
如果需要使用this来获取组件实例处理逻辑,则应该在next中增加回调函数进行处理,回调函数的参数即为组件实例。

beforeRouteEnter(to, from, next){
    next(vm => {
        //在这里vm即我们熟知的this
        ...
    })
}

3.更新守卫

仅当路由的参数发生变化时调用。由于在这种情况下,需要渲染的组件相同,因此组件实例被复用。由于是复用组件,因此不会触发路由的前置、后置守卫。在这种情况下,用于监听页面变化,功能上代替前置守卫的即beforeRouteUpdate
在该守卫中,可以直接使用this获取组件实例。

beforeRouteUpdate(to, from, next){
    //可以使用this
    next();
    //可以使用this
}

4.后置守卫

顾名思义,在路由即将离开之际被调用。同样可以使用this获取组件实例。

beforeRouteLeave(to, from, next){
    //可以使用this
    next();
    //可以使用this
}

5.几个注意点

前边根据文档大概介绍了一下组件内导航守卫。这里把在实践中遇到的几个问题、容易犯错的地方说一说。

5.1

只能在前置守卫的next函数中设置参数回调!

5.2

任何一个守卫中都必须执行next()来resolve守卫!否则路由过程就会中断!
开始读文档的时候,没有认真读完,只是针对要使用的地方大致看了一眼。文档中提到在更新守卫和后置守卫中,已经可以直接使用this来获取组件实例,没有必要也不支持给next传递回调。这里我在beforeRouteUpdate中想当然的就把next也直接干掉了(犯2),结果发现执行路由的时候,页面参数一直不变。其实是因为没有执行next导致路由中断。
因此,如果在路由组件不变只改变参数的路由中,发现url的参数一直不按照预想的发生变化,看一看是不是更新守卫中没有执行next

5.3

更新守卫中,使用this.$route.params来获取路由参数,在next执行之前时,拿到的是from路由的参数(旧页面),在next执行之后,拿到的是to路由的参数(新页面)。

OVER。


wei4118268
88 声望1 粉丝

前端从业者