vue-router提供的导航守卫主要用来通过跳转或取消的方式守卫导航(也就是路由跳转过程中的一些钩子函数)
参数或查询的改变并不会触发进入/离开的导航守卫
1.导航守卫的调用顺序
- 导航被触发。
- 在失活的组件(跳转前的组件)里调用
beforeRouteLeave守卫。 - 调用全局的
beforeEach守卫。 - 在重用的组件里调用
beforeRouteUpdate守卫 (2.2+)。 - 在路由配置里调用
beforeEnter。 - 解析异步路由组件。
- 在被激活的组件里调用
beforeRouteEnter。 - 调用全局的
beforeResolve守卫 (2.5+)。 - 导航被确认。
- 调用全局的
afterEach钩子。 - 触发
DOM更新。(beforeCreate=>created=>beforeMount=>mounted) - 调用
beforeRouteEnter守卫中传给next的回调函数,创建好的组件实例会作为回调函数的参数传入。
-
beforeRouteLeave(组件离开)=>beforeEach(前置钩子)=>beforeRouteUpdate(组件更新)=>beforeEnter(路由独享)=>beforeRouteEnter(组件确认)=>beforeResolve(解析)=>afterEach(后置钩子)=>beforeRouteEnter里的next()回调函数全部的路由守卫:
- 全局路由钩子:
beforeEach(to,from, next)、beforeResolve(to,from, next)、afterEach(to,from) - 独享路由钩子:
beforeEnter(to,from, next) - 组件内路由钩子:
beforeRouteEnter(to,from, next)、beforeRouteUpdate(to,from, next)、beforeRouteLeave(to,from, next)2.详解各个导航守卫
2.1全局导航守卫(三个)
2.1.1. 全局前置守卫(
主要作用于登录验证,未跳转前告知router.beforeEach)
全局守卫按照创建顺序调用,守卫是异步解析;此时导航在所有守卫resolve完之前一直处于等待中 ```javascript const router = new VueRouter({ … })
router.beforeEach((to, from, next) => { // … })
<a name="N6PLJ"></a>#### 2.1.2.每个守卫接受三个参数1. **`to`**:即将要进入的目标路由对象1. **`from`**:即将要要离开的路由对象1. **`next`**:一定要调用该方法来 resolve 这个钩子1. 凡是涉及到有`next`参数的钩子,必须调用`next()`才能继续往下执行(可出现多次,但不能影响已有逻辑,否则永远不会解析或报错),否则路由跳转等会停止1. 中断导航使用`next(false)`1. `next('/')`或者`next({ path: '/' })`:跳转到一个不同的地址1. 且允许设置诸如 `replace: true`、`name: 'home'` 之类的选项以及任何用在 `router-link` 的 `to` `prop` 或 `router.push` 中的选项4. `next(error)`:导航会被终止且该错误会被传递给 router.onError() 注册过的回调<a name="6oEbv"></a>#### 2.1.2. 全局解析守卫(`router.beforeResolve`)(2.5.0增)用`router.beforeResolve`注册一个全局守卫。这和`router.beforeEach`类似,区别是在导航被确认之前,**同时在所有组件内守卫和异步路由组件被解析之后**,解析守卫就被调用。<a name="zail8"></a>#### 2.1.3. 全局后置守卫(`router.afterResolve`)没有`next`参数,也不会改变导航本身```javascriptrouter.afterEach((to, from) => {// ...})
2.2. 路由独享的守卫(beforeEnter)
可以在路由配置上直接定义该守卫
const router = new VueRouter({routes: [{path: '/foo',component: Foo,beforeEnter: (to, from, next) => {// ...}}]})
2.3. 组件内的守卫(三个)
2.3.1.beforeRouteEnter
- 不能访问
this - 支持给
next传递回调的唯一守卫(后面不支持,是因为已经支持this了,没必要)const Foo = {template: `...`,beforeRouteEnter (to, from, next) {next(vm => {// 通过 `vm` 访问组件实例})}}
2.3.2.
beforeRouteUpdate(2.2增)beforeRouteUpdate (to, from, next) {this.name = to.params.namenext()}
2.3.3.
通常用来禁止用户在还未保存修改前突然离开beforeRouteLeavebeforeRouteLeave (to, from, next) {const answer = window.confirm('Do you really want to leave? you have unsaved changes!')if (answer) {next()} else {next(false)}}
