发布于 

导航守卫的理解

导航守卫主要用来通过跳转或取消的方式守卫导航

​ 简单来说就是路由跳转过程中的一些钩子函数

扩展:

钩子函数执行顺序:

全局前置守卫:beforeEach——>路由beforeEnter守卫——>组件路由守卫beforeRouteEnter(this并不指向该组件实例)——>全局解析守卫:beforeResolve——>全局后置守卫:afterEach——>组件生命周期:beforeCreate——>组件生命周期created——>组件生命周期beforeMount——>组件声明周期mounted——>组件路由守卫beforeRouteEnter的next回调

导航守卫分为:

全局单个路由独享组件内三种。

全局:指路由实例上直接操作的钩子函数,所有路由配置的组件都会触发,大白话就是触发路由就会触发这些钩子函数。

beforeEachbeforeResolve(2.5+)afterEach

1
2
3
4
5
6
const router = new VueRouter({

router.beforeEach((to, from, next) => {
....
})
})

[beforeEach] :在路由跳转前触发,参数包括to,from,next作用:用于登录验证,路由没跳转前告知

[beforeResolve](2.5+) :以上类似,官方文档:区别是在导航被确认之前,同时在所有组件内守卫和异步路由组件被解析之后,解析守卫就被调用。

[afterEach]:在路由跳转后触发,参数to ,from 发生在beforeEach和beforeResolve之后,beforeRouteEnter之前

路由独享:指单个路由配置的时候设置钩子函数

1
2
3
4
5
6
7
8
9
10
11
const router = new VueRouter({
roues: [
{
path: '',
component: ,
beforeEnter: (to, from ,next) => {
....
}
}
]
})

[beforeEnter] :和…Each相同,都设置在…Each之后执行参数to,from,next

组件内:指在组件内执行钩子函数,类似组件的生命周期,相当于为路由组件添加生命周期钩子函数

beforeRouteEnterbeforeRouteUpdate(2.2+)beforeRouteLeave

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
export default {
name: '',
data () {
return {
....
}
},
beforeRouteEnter (to, from, next) {
// 在渲染组件的对用路由被confirm前调用
// 不能用this!!不能用this!!不能用this!!
// this并不指向该组件实例
},
beforeRouteUpdate (to, from, next) {
// 当前路由改变,组件被复用时调用
// 可以访问组件实例!!this!!
},
beforeRouteLeave (to, from, next){
// 导航离开组件的对应路由时调用
// 可以访问组件实例 !!this!!
}
}

[beforeRouteEnter] :路由之前调用,参数to,from,next

在全局守卫beforeEach和独享守卫beforeEnter之后,全局beforeResolve和全局afterEach之前调用。在beforeCreate生命周期前触发。

注:该守卫访问不到组件实例,this为undefined

★★★可以通过传一个回调给next来访问组件实例,在导航被确认的时候执行回调,并且把组件实例作为回调方法的参数,可以在这个守卫中请求服务端获取数据,当成功获取并能进入路由时,调用next并在回调中通果vm访问组件实例进行赋值等操作需注意的是next中函数的调用在mounted之后:主要是为了确保能对组件实例的完整访问

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

[beforeRouteUpdate] (2.2+) :路由改变时,且组件被复用时调用(this可以!!!)参数:to,from, next

★★什么时候路由改变? && 什么时候组件被复用?

1.带有动态参数的路径

2.路由query变更时,该守卫会被调用

★★★补充:query和params的用法区别

query:

1
2
3
4
5
6
7
this.$router.push({
path: '',
query: {
type: ,
typeDesc:
}
})

【query用path引入,params要用name引入。接收参数类似:this.$route.query.namethis.$route.params.name query在浏览器地址中显示参数params则不显示

【注:query刷新不会丢失query里面的数据。params刷新会丢失params里面的数据】看需求使用

​ 如:刷新获取不同的值用params,反之就用query】

params:

1
2
3
4
5
6
7
this.$router.push({
name: '',
params: {
type: ,
typeDesc:
}
})

[beforeRouteLeave] :导航组件离开组件的对应路由时调用(this可以!!!)

参数:to, from, next

回调参数:【重点★★★★】

to: 目标路由对象

from:离开的路由对象

next:下一个钩子

值得注意的是但凡涉及到next参数的钩子,需调用next()才能继续执行下一个钩子,否则路由跳转会停止。还有就是如果要中断当前的导航要调用next(false)【用于登录验证不通过处理】,URL的改变(手动或浏览器回退按钮)会让URL地址重置到from路由对应的地址。当然next也可以如以下方法使用:next(‘/’)或next({path:‘/’}):跳转到一个不同的地址。白话就是当前导航被中断,则执行一个新的导航。参数router.push一致

beforeRouteEnter钩子中的next((vm)=> {})内接受的回调函数参数为当前组件的实例vm,在生命周期mounted之后调用。最后执行的钩子函数

next(error):(v2.4.0+)如果传入next的参数是一个Error实例,则导航会被终止该错误会被传递给router.onError注册过得回调

被调用的错误如以下情形:

  • 错误在一个路由守卫函数中被同步抛出;
  • 错误在一个路由守卫函数中通过调用 next(err) 的方式异步捕获并处理;
  • 渲染一个路由的过程中,需要尝试解析一个异步组件时发生错误。

本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。