vue笔记 - 导航钩子(路由守卫)

守卫分类

  • 全局守卫: router.beforeEach
  • 全局解析守卫:router.beforeResolve
  • 全局后置钩子:router.afterEach
  • 路由独享守卫:beforeEach
  • 组件内的守卫:beforeRouteEnter、beforeRouteLeave、beforeRouteUpdate(vue2.2+)

作用
通过跳转或取消的方式守卫导航。
PS:参数或查询的改变不会触发进入/离开的导航守卫。

1、全局守卫

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

to: 即将进入的路由对象
from: 当前导航正要离开的路由对象
next: 通过这个方法来resolve导航钩子.

  • next():进行管道中的下一个钩子,如果全部钩子执行完毕,则导航的状态是confirmed(确认).
  • next(false):终端当前导航,如果浏览器URL改变了,则URL充值到from路由地址
  • next("/"):可写为next({path:"/"})当前的导航被中断,然后进入新的导航.
  • next(error):(vue2.4+)r如果传入的next参数是一个Error实例,则导航会被终止且Error会被传递给router.onError()注册过的回调.
    PS:确保next()被调用,否则钩子不会执行resolved

2、全局解析守卫(vue2.5+)
通过router.beforeResolve注册一个全局守卫. 和router.beforeEach类似, 区别是在导航被确认之前, 同时在所有组件内守卫和异步路由组件被解析之后,解析守卫就被调用.

3、全局后置钩子
通过router.afterEach注册, 这些钩子不会接受next函数也不会改变导航本身

router.afterEach((to, from) => {
     
	//coding
})

4、路由独享守卫

const router = new Vue.VueRouter({
     
	route:[
		{
     
			path:'/home',
			component:Home,
			beforeEach:(to, from, next) =>{
     
				//coding
			}
		}
	]
})

组件内的守卫

const Home = {
     
	template: `
Home
`
, beforeRouteEnter(to, from, next){ next(vm =>{ //coding }) // 在渲染该组件的对应路由被 confirm 前调用 // 组件实例未创建,无法获取组件实例 `this` //可以通过回调next的方式访问组件实例 }, beforeTouteUpdate(to, from, next){ //当前路由改变,但该组件被复用时调用(如:/home/:id中,在/home/1和/home/2中间跳转时) //可以访问组件实例this }, beforeRouteLeave(to,from, next){ //导航离开组件时调用 //可以访问组件实例this } //PS:beforeTouteEnter是支持给next传递回调的唯一守卫,beforeTouteUpdate和beforeRouteLeave中,this已经可用了 }

例子:

<!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: '
bar-{ {userId}}
'
, computed: { userId() { return this.$route.params.userId } }, //组件内的守卫 beforeRouteEnter (to, from, next) { console.log('beforeRouteEnter') next() }, beforeRouteUpdate (to, from, next) { console.log('beforeRouteUpdate') next() }, beforeRouteLeave (to, from, next) { console.log('beforeRouteLeave') next() } } const error = { template: '
oops! error
'
} const home = { template: '
this is home
'
} 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') next() // 跳转到指定页面 // 不能直接next('/error'),会陷入死循环 // to.path == '/error' ? next() : next('/error') // 只能停留在当前页面 // next(false) }) // 全局解析守卫 router.beforeResolve((to, from, next) => { console.log('beforeResolve') next() }) // 全局后置钩子 router.afterEach((to, from) => { console.log('afterEach') }) const app = new Vue({ el: "#app", router }) </script> </body> </html>

你可能感兴趣的:(vue)