结论先行:
路由守卫/导航钩子:指路由跳转的时候所触发的钩子函数。主要用于控制导航跳转。
Vue 路由导航守卫分为全局守卫、路由独享守卫、组件内置守卫
1、全局守卫
① beforeEach 全局前置导航钩子,路由进入之前触发,用来身份验证、路由拦截等操作。
② beforeResolve 路由确认之前
③ afterEach 全局后置导航钩子,路由进入之后触发,用来进行路由跳转后的操作,比如页面滚动、统计PV等操作
2、路由独享守卫
beforeEnter 路由进入之前。对某个特定路由进行独立的前置验证或权限控制。
3、组件内置守卫
beforeRouteEnter 路由进入之前,一般用来初始化数据,此时组件还没被创建出来,因此 this 是 undefined
beforeRouteUpdate 路由更新之前
beforeRouteLeave 路由离开之前, 一般用来进行页面数据的保存或弹出提示等操作。
具体分析:
一、作用
路由守卫就是路由跳转的时候会触发的钩子函数我们把他称为路由守卫。
Vue Router 提供了多种导航钩子,可以在导航过程中执行相应的操作。
作用:可以控制导航跳转,例如 beforeEach,afterEach 等;一般用于页面 title 的修改。还有一些需要登录才能调整页面的重定向功能。
二、常用的导航钩子
Vue 路由导航守卫分为全局守卫、路由独享守卫、组件内置守卫
1、全局守卫
beforeEach 路由进入之前
beforeResolve 路由确认之前
afterEach 路由进入之后
① beforeEach 全局前置导航钩子
在每个路由跳转之前执行,可以用来进行用户身份验证、路由拦截等操作。
beforeEach 主要有3个参数 to,from,next。
to:即将进入的目标路由对象;
from:当前导航正要离开的路由。
next:一定要调用该方法,resolve这个钩子。可以控制网页的跳转。
next() // 直接进to所指的路由 next(false) // 中断当前路由 next('route') // 跳转指定的路由名称 next('error') // 跳转错误的路由名称 next({ path: 'xxxx' }) // 跳转到xxx的路由路径上
② beforeResolve 全局解析守卫
在每个路由跳转被确认之前调用,可以用于处理异步路由组件。
参数都是 to from next,这个在开发中几乎不用。
③ afterEach 全局后置导航钩子
在每次路由跳转之后执行,可以用来进行路由跳转后的操作,比如页面滚动、统计PV等操作
afterEach 不接收第三个参数 next 函数,也不会改变导航本身,开发中用得较少。
// 前置守卫
async function handleBeforeEach(to, from, next) {
const page = to.path
const isWhiteList = ['/xxx'].includes(page)
// 在白名单内,直接放行
if (isWhiteList) {
next()
return
}
// 不在白名单内,判断是否有token
const token = getToken()
if (!token) {
// 无token,跳转到登录页
next({ path: '/login', replace: true })
return
}
next()
}
// 后置守卫
function handleAfterEach(to, from) {
console.log(to, from)
}
// 绑定路由权限
export default function permission(router) {
router.beforeEach(handleBeforeEach)
router.afterEach(handleAfterEach)
return router
}
2、路由独享守卫
① beforeEnter 路由进入之前
在进入某个特定路由前调用,与全局 beforeEach 的区别是它可以针对某个具体路由进行设置。也就是可以用于对该路由进行独立的前置验证或权限控制。
const router = new VueRouter({
routes: [
{
path: '/home',
component: Home,
beforeEnter: (to, from, next) => {
// 在进入 /home 路由前执行的逻辑
// 可以进行验证或权限控制
next();
}
},
// ...
]
});
3、组件内置守卫
beforeRouteEnter 路由进入之前
beforeRouteUpdate 路由更新之前
beforeRouteLeave 路由离开之前
① beforeRouteEnter 路由进入之前
组件还没被创建出来,因为函数内部 this 是undefined
先执行 beforeRouteEnter ,再执行组件内部钩子函数 beforeCreate
data() {
return {
}
},
beforeRouteEnter (to, from, next) {
if (to.meta.needLogin) {
next(vm => {
vm.needLogin = true
})
} else {
next()
}
}
② beforeRouteUpdate 路由更新之前
在路由更新时执行,比如路由参数发生变化时。
开发中比较少用
③ beforeRouteLeave 路由离开之前
在离开当前路由时执行,可以用来进行页面数据的保存或弹出提示等操作。
// 路由跳转之前保存当前滚动条的位置。
beforeRouteLeave(to, from, next) {
this.scroll = document.getElementsByClassName(
"el-table__body-wrapper"
)[0].scrollTop;
next();
},
4、总结
这些导航钩子提供了灵活的路由跳转控制机制,可以方便地实现各种复杂的路由跳转需求。
同时,VueRouter 还提供了一些其他的导航钩子和高级特性,比如路由元信息、动态路由、命名路由等,可以进一步提高开发效率和应用的可维护性。
三、全局守卫、路由独享守卫、组件内置守卫的区别
1、作用范围不同
全局守卫:作用于所有页面;
路由独享守卫:守卫单个路由;
组件内置守卫:作用于单个组件;
2、代码写的位置不一样
全局守卫:写在 router/index.js 中;
路由独享守卫:写在路由规则里;
组件内置守卫:写在组件里 跟 data 同级;
3、执行顺序
beforeEach 【全局 - 进入之前】
beforeEnter【路由独享 - 进入之前】
beforeRouteEnter 【组件内置守卫 - 进入之前】
beforeResolve 【全局 - 解析】
afterEach 【全局 - 进入之后】