vue vue-router 各个守卫的详细理解

导航守卫分类

导航守卫按照维度分三个:

全局的:进入任何一个路由都会执行

  • beforeEach:进入路由前执行
  • beforeResolve:在导航被确认之前,同时在所有组件内守卫和异步路由组件被解析之后,解析守卫就被调用
  • afterEach:导航确认执行时执行,可理解为导航完成时执行

路由的:进入某个路由才会执行

  • beforeEnter: 进入该路由前

组件的:进入某个组件才会执行组件复用时

  • beforeRouteEnter: 进入组件时
  • beforeRouteUpdate: 组件被复用时调用
  • beforeRouteLeave: 离开组件前

例子

这么多的函数,执行先后顺序是什么呢,如何使用?请看下面的例子:

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>vue-router</title>
	<script src="vue.js"></script>
	<script src="vue-router.js"></script>
</head>
<body>
	<div id="app">
		<router-view></router-view>
	</div>
	<script>
		const bar = { 
			template: '<div>bar-{{userId}}</div>',
			computed: {
				userId() { return this.$route.params.userId }
			},
			beforeRouteEnter (to, from, next) {
			  // 在渲染该组件的对应路由被 confirm 前调用
			  // 不!能!获取组件实例 `this`
			  // 因为当守卫执行前,组件实例还没被创建
			  console.log('beforeRouteEnter')
			  next()
			},
			beforeRouteUpdate (to, from, next) {
			  // 在当前路由改变,但是该组件被复用时调用
			  // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
			  // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
			  // 如果不加这个钩子,则路由变化时页面检测不到数据变化
			  // 可以访问组件实例 `this`
			  console.log('beforeRouteUpdate')
			  next()
			 },
			 beforeRouteLeave (to, from, next) {
			  // 导航离开该组件的对应路由时调用
			  // 可以访问组件实例 `this`
			  console.log('beforeRouteLeave')
			  next()
			}
		}
		const error = { template: '<div>oops! error</div>'}
		const home = { template: '<div>this is home</div>'}

		const routes = [
			{ path: '/error', component: error },
			{ path: '/', component: home },
			// 路由独享守卫,用法与beforeEach一样
			{ path: '/bar/:userId', component: bar, beforeEnter: ((to, from, next) => {
					console.log('beforeEnter')
					next()
				})
			}
		]

		const router = new VueRouter({
			routes
		})

		// 全局前置守卫: 进入to路由前执行
		router.beforeEach((to, from, next) => {
			console.log('beforeEach')
			console.log(to)
			console.log(from)
		// 正常跳转到下一个页面,
			next()
		// 跳转到指定页面 
			// 不能直接next('/error'),会陷入死循环 参考https://segmentfault.com/q/1010000012316727q/1010000012316727
			// to.path == '/error' ?  next() : next('/error')
		// 只能停留在当前页面
			// next(false)
		})

		// 全局解析守卫: 在导航被确认之前,同时在所有组件内守卫和异步路由组件被解析之后,解析守卫就被调用
		router.beforeResolve((to, from, next) => {
			console.log('beforeResolve')
			// console.log(to)
			// console.log(from)
			next()
		})

		// 全局后置钩子: 导航被确认执行,可以理解为导航完成时执行
		router.afterEach((to, from) => {
			console.log('afterEach')
			// console.log(to)
			// console.log(from)
		})

		const app = new Vue({
			el: "#app",
			router
		})
	</script>
</body>
</html>

导航守卫的解析流程

在上面的代码中加入了所有的守卫导航函数,下面来看看几种情况导航守卫的解析流程:

首先进入  '/bar/123'  即进入一个组件可以看到,控制台打印为:

然后我们将路径更改为:'/bar/234‘,复用组件

'

最后更改为 ’/home' ,离开组件

从上面可以很好地理解导航的解析流程。

一些小坑

  • next()

对于有next()的钩子函数

        // 正常跳转到下一个页面,
            next()
        // 跳转到指定页面 
            // 不能直接next('/error'),会陷入死循环 参考https://segmentfault.com/q/1010000012316727q/1010000012316727
            to.path == '/error' ?  next() : next('/error')
        // 只能停留在当前页面
            next(false)

  • beforeRouteUpdate

如果不加这个钩子,则路由变化时,页面检测不到数据变化:

             beforeRouteUpdate (to, from, next) {
               next()
             }

发布了53 篇原创文章 · 获赞 12 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/bingqise5193/article/details/102959259