官网API
导航守卫的作用:vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航。
项目中应用场景:路由页面跳转时候进行登陆验证;路由跳转判断;
有多种机会植入路由导航过程中:全局路由, 单个路由独享的, 或者组件级的。
全局守卫包括:router.beforeEach(全局前置守卫)、router.beforeResolve(全局解析守卫)、router.afterEach(全局后置钩子)
单个路由独享的导航守卫:在路由配置上直接定义 beforeEnter 守卫
组件内守卫包括:在组件内定义路由的导航守卫,有beforeRouteEnter 、beforeRouteUpdate 、beforeRouteLeave
每个导航守卫都接受3个参数 from 、to、next() ,参数的定义如下:
to: Route: 即将要进入的目标 路由对象
from: Route: 当前导航正要离开的路由
next: Function: 一定要调用该方法来 resolve 这个钩子。执行效果依赖 next 方法的调用参数。
next(): 进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 confirmed (确认的)。
next(false): 中断当前的导航。如果浏览器的 URL 改变了 (可能是用户手动或者浏览器后退按钮),那 么 URL 地址会重置到 from 路由对应的地址。
next(’/’) 或者 next({ path: ‘/’ }): 跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。你可以向 next 传递任意位置对象,且允许设置诸如 replace: true、name: ‘home’ 之类的选项以及任何用在 router-link 的 to prop 或 router.push 中的选项。
next(error): (2.4.0+) 如果传入 next 的参数是一个 Error 实例,则导航会被终止且该错误会被传递给 router.onError() 注册过的回调。
注意事项:
1、确保要调用 next 方法,否则钩子就不会被 resolved。
2、当一个导航触发时,导航守卫按照顺序调用。守卫是异步解析执行,导航在所有守卫 resolve 完之前一直处于 等待中。
源码: to:Route, to是route类型 route就是router/index.js 里面定义的一个个路由
所以在route里面加入元数据meta (描述数据的数据)
router/index.js
{
path:'/home',
component: Home ,
meta:{
title:'首页'
}
}
...
//前置钩子 跳转之前回调
router.beforeEach((to,from,next) =>{
//从from跳转到to
document.title = to.matched[0].meta.title //to里面没有title,要去route里面加入
//不写 matched[0] 第一个路由会显示为undefind
console.log(to)
next()//是必须要调用的
})
router.beforeEach 在每次进入页面和页面刷新时都要经过该守卫判断
使用:
import Vue from 'vue'
import VueRouter from 'vue-router'
import Index from '../views/Index.vue'
import {routerList} from '../router/RouterList.js'
Vue.use(VueRouter)
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes:routerList
})
router.beforeEach((to,from,next)=>{
if(to.path == '/page-1'){
next({path:'/page-3'})
}else{
next()
}
})
export default router
参数值:to from next
to: Route: 即将要进入的目标 路由对象
from: Route: 当前导航正要离开的路由
next: Function: 一定要调用该方法来 resolve 这个钩子(如果没有调用页面进程会反复调用)
使用:next(’/’) 或者 next({ path: ‘/’ }): 跳转到一个不同的地址。当前的导航被中断,然后进行一个新 的导航。你可以向 next 传递任意位置对象,且允许设置诸如 replace: true、name: ‘home’ 之类的选项以及任何用在 router-link 的 to prop 或 router.push 中的选项。
router.beforeResolve和 router.beforeEach 类似,区别是在导航被确认之前,同时在所有组件内守卫和异步路由组件被解析之后,解析守卫就被调用
使用:
import Vue from 'vue'
import VueRouter from 'vue-router'
import Index from '../views/Index.vue'
import {routerList} from '../router/RouterList.js'
Vue.use(VueRouter)
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes:routerList
})
router.beforeRouteLeave((to,from,next)=>{
if(to.path == '/page-1'){
next({path:'/page-3'})
}else{
next()
}
})
export default router
router.afterEach 页面进入之后执行 不会接受 next 函数也不会改变导航本身,不需要主动调用next()函数
使用:
import Vue from 'vue'
import VueRouter from 'vue-router'
import Index from '../views/Index.vue'
import {routerList} from '../router/RouterList.js'
Vue.use(VueRouter)
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes:routerList
})
router.afterEach((to,form)=>{
console.log(to)
})
export default router
参数:to from
to: Route: 即将要进入的目标 路由对象
from: Route: 当前导航正要离开的路由
beforeEnter你可以在路由配置上直接定义 beforeEnter 守卫
使用:
{
path: '/',
redirect: '/page-1',
name: 'index',
component: () => import ('../views/Index.vue'),
children: [
{
path: '/page-1',
name: 'Page-1',
component: () =>import ('../views/page1/page-1.vue'),
beforeEnter: (to, from, next) => {
console.log(to)
next()
}
},
{
path: '/page-2',
name: 'Page-2',
component: () =>
import ('../views/page2/page-2.vue')
},
]
参数: to from next 这些守卫与全局前置守卫的方法参数是一样的(必须调用next())
beforeRouteEnter:在渲染该组件的对应路由被 confirm 前调用 ,不能!获取组件实例 this 因为
当守卫执行前,组件实例还没被创建
beforeRouteUpdate: (2.2 新增)在当前路由改变,但是该组件被复用时调用举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳
由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。转的时候,
可以访问组件实例 this
beforeRouteLeave:导航离开该组件的对应路由时调用 可以访问组件实例 this
使用:
<template>
<div>page2div>
template>
<script>
// eslint-disable-next-line @typescript-eslint/no-this-alias
export default {
data() {
return {
}
},
beforeRouteEnter(to, from, next) {
// ...
console.log(to);
next();
},
beforeRouteLeave(to, from, next) {
console.log(to);
next();
},
// eslint-disable-next-line @typescript-eslint/no-empty-function
beforeRouteUpdate(to, from, next) {
console.log(to);
next();
}
};
script>
<style lang="less" scoped>
style>