浅聊一下
当使用 Vue.js 构建单页应用时,Vue Router 是一个常用的路由管理库。它提供了导航守卫(Navigation Guards)机制,用于在路由切换前、切换后或切换取消时执行自定义逻辑。本文将介绍 Vue Router 导航守卫的概念和使用方法。 Vue Router 提供了全局前置守卫、全局解析守卫、全局后置守卫以及路由独享守卫和组件内的守卫等多种类型的守卫。在本文中,我们将深入探讨这些导航守卫的用法,并提供实例来帮助您更好地理解其工作原理。通过使用导航守卫,您可以更灵活地管理和控制路由的跳转行为,为您的应用程序增加更多的功能和安全性。
导航守卫
正如其名,vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航。这里有很多方式植入路由导航中:全局的,单个路由独享的,或者组件级的。
全局守卫
先来一个简单的页面用来演示我们要讲到的全局守卫,点击首页显示Home,点击关于显示About
1. 全局前置守卫 beforeEach
beforeEach
是 Vue Router 中的一个全局前置守卫。它允许我们在每次路由切换之前执行一些操作或者进行一些验证。
具体来说,beforeEach
方法接收三个参数:to
、from
和 next
。to
表示即将跳转的目标路由对象,from
表示当前导航正要离开的路由对象,而 next
是一个必须调用的函数,用于确认导航过程是否继续。 我们在index.js中添加以下这段代码:
js
router.beforeEach((to,from,next)=>{
console.log(to,from);
document.title = to.meta.title
if(to.path != '/'){
const isLogin = localStorage.getItem('isLogin')
if(isLogin){
next()
}else{
alert('未登录')
return
}
}
next()
})
我们先看看当beforeEach触发以后打印的to和from是什么
里面保存了我们要离开的页面和要去的页面的相关信息...上面这段代码主要有一个限制权限的作用,只要你没有登录,就让你只能访问首页,因为没有写登录页面,所以用一个简易的弹窗代替...来看看效果
此时页面并不发生跳转。细心的掘友会发现里面还有一个meta属性,这个属性可以用来更改标签页的标题
在路由里设置了这样的一个meta,这样在全局前置守卫中通过 document.title = to.meta.title
,就可以将标题修改了
2. 全局的解析守卫 beforeResolve
全局的解析守卫(全局解析守卫)在 Vue Router 中是一种导航守卫,用于在路由切换之前解析异步数据。这个守卫会在所有路由跳转之前被调用,确保在路由切换时已经准备好需要的数据。
全局解析守卫可以用来处理一些需要在路由跳转前获取的数据,例如从后端API请求数据、执行一些异步操作等。通过使用全局解析守卫,我们可以确保在路由切换时数据已经准备就绪,避免页面加载时数据未完全获取而导致的显示问题。
简单地说,全局的解析守卫就是在页面将要进行跳转之时调用,一般用来执行一些异步操作,确保跳转之后数据完全加载到了
3. 全局后置钩子 afterEach
用于在路由切换之后执行一些操作。这个守卫会在所有路由跳转完成之后被调用,无论是成功还是失败。
全局后置钩子可以用来处理一些需要在路由跳转后执行的操作,例如页面统计、记录日志等。通过使用全局后置钩子,我们可以确保在每次路由跳转完成后都能执行必要的操作。
举一个很常见的例子,掘友们在上网的时候,点击跳转到第二个页面时,立马就加载起了广告,这就是可以使用afterEach来完成的一个效果
路由独享守卫 beforeEnter
从名字上来看,我们就能理解beforeEnter是在路由跳转之前生效,独享守卫又说明这个beforeEnter可以被单独用在一个路由里,如下代码,在about路由添加一个beforeEnter
js
const routes = [
{
path:'/',
name:'home',
component:()=>import('../views/home.vue'),
meta:{
title:'首页'
}
},
{
path:'/about',
name:'about',
component:()=>import('../views/about.vue'),
meta:{
title:'关于'
},
//路由的独享守卫
beforeEnter:(to,from,next)=>{
console.log(to,from);
next()
}
}
]
这个beforeEnter是about独有的,所以只会在进入about之前会生效
组件内的守卫
在使用选项式API的时候,vue-router提供了三种组件内的守卫
beforeRouteEnter
beforeRouteUpdate
beforeRouteLeave
他们分别在路由进入组件之前、当前路由改变,但是该组件被复用时、在离开当前组件对应的路由时被调用,我们将他们写在组件内
js
const UserDetails = {
template: `...`,
beforeRouteEnter(to, from) {
// 在渲染该组件的对应路由被验证前调用
// 不能获取组件实例 `this` !
// 因为当守卫执行时,组件实例还没被创建!
},
beforeRouteUpdate(to, from) {
// 在当前路由改变,但是该组件被复用时调用
// 举例来说,对于一个带有动态参数的路径 `/users/:id`,在 `/users/1` 和 `/users/2` 之间跳转的时候,
// 由于会渲染同样的 `UserDetails` 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
// 因为在这种情况发生的时候,组件已经挂载好了,导航守卫可以访问组件实例 `this`
},
beforeRouteLeave(to, from) {
// 在导航离开渲染该组件的对应路由时调用
// 与 `beforeRouteUpdate` 一样,它可以访问组件实例 `this`
},
}
当我们使用组合式API的时候,vue-router提供了两种组件内的守卫
onBeforeRouteUpdate
onBeforeRouteLeave
这里我们举onBeforeRouteLeave的例子
js
onBeforeRouteLeave((to,from,next)=>{
console.log(to,from)
const flag = window.confirm('你确定要离开这个页面吗?')
if(flag){
next()
}
} )
当我们点击首页要离开about的时候,跳出弹窗,点击确定则离开
结尾
vue-router导航守卫详解到此结束,看完这篇文章,导航守卫就已经难不倒你啦!