vue3中路由守卫的快速上手

news/2024/11/25 19:31:36/

路由守卫或者说路由拦截,在我们实际开发前端项目中是经常用到的操作;

通过路由守卫,可以在用户访问某个路由之前进行权限验证。(全局前置守卫)例如,可以检查用户是否登录,是否具有访问该路由的权限,如果不满足条件,则可以将用户重定向到其他页面或显示相应的提示信息。

全局前置守卫(在每次路由跳转之前被触发)

可以使用 router.beforeEach 注册一个全局前置守卫

// 前置守卫router.beforeEach((to, from) => {}
)

当一个导航触发时,全局前置守卫按照创建顺序调用。守卫是异步解析执行,此时导航在所有守卫 resolve 完之前一直处于等待中

每个守卫方法接收两个参数:

to: 即将要进入的目标 

from: 当前导航正要离开的路由 

可以返回的值如下:

  • false: 取消当前的导航。如果浏览器的 URL 改变了(可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到 from 路由对应的地址。
  • 一个路由地址: 通过一个路由地址重定向到一个不同的地址,如同调用 router.push(),且可以传入诸如 replace: true 或 name: 'home' 之类的选项。它会中断当前的导航,同时用相同的 from 创建一个新导航。
// 前置守卫
// 全局拦截、除了登录页面,其他页面都必须授权(这里为pinia定义的token不为空)才能访问
router.beforeEach((to, from) => {
const useToken=useTokenStore()
if (to.name !== 'login' && !useToken.token) {return { name: 'Login' }
}
else{return true}
}
)

在这个路由全局拦截方法中,我们规定如果只有login页面才能被所有人访问,访问的页面不是login页面都要有身份认证(pinia定义的token)才行,如果没有、则会自动跳到login登录页面,这在我们前端开发中是经常用到的。

如果遇到了意料之外的情况,可能会抛出一个 Error。这会取消导航并且调用 router.onError() 注册过的回调。

如果什么都没有,undefined 或返回 true则导航是有效的,并调用下一个导航守卫

可选的第三个参数 next

在之前的 Vue Router 版本中(vue-router3),还可以使用 第三个参数 next 。在最新版的vue-router4版本中,官方移除了next参数,推荐我们只使用to、from这两个参数。然而,它仍然是被支持的,这意味着你可以向任何导航守卫传递第三个参数。

在这种情况下,确保 next 在任何给定的导航守卫中都被严格调用一次它可以出现多于一次,但是只能在所有的逻辑路径都不重叠的情况下,否则钩子永远都不会被解析或报错。

错误的next使用方法:(这时,如果用户没有携带token,那么next会被调用两次)

// 前置守卫
// 全局拦截、除了登录页面,其他页面都必须授权(这里为pinia定义的token不为空)才能访问
router.beforeEach((to, from, next) => {
const useToken=useTokenStore()
if (to.name !== 'login' && !useToken.token) {next({name: 'login'})
}next()}
)

正确的用法:(务必确保next只被调用一次)

// 前置守卫
// 全局拦截、除了登录页面,其他页面都必须授权(这里为pinia定义的token不为空)才能访问
router.beforeEach((to, from, next) => {
const useToken=useTokenStore()
if (to.name !== 'login' && !useToken.token) {next({name: 'login'})
}
else{next()
}
}
)

全局后置钩子(在每次路由跳转之后被触发)

可以注册全局后置钩子,然而和守卫不同的是,这些钩子不会改变导航本身

// 后置守卫
router.afterEach((to, from) => {
console.log('路由跳转的路径====>',to.path)
}
)

一般来说,我们经常使用前置钩子,因为它能够在我们跳转路由之前进行拦截。后置钩子我们一般用于分析、记录日志、声明页面等辅助功能以及许多其他事情都很有用。

全局解析守卫

可以用 router.beforeResolve 注册一个全局守卫。它在每次导航时都会触发,不同的是,解析守卫刚好会在导航被确认之前、所有组件内守卫和异步路由组件被解析之后调用。这意味着在路由对象被创建之后,但还没有被解析或渲染时,全局解析守卫将会被触发。

router.beforeResolve( to => {if (to.meta.requiresCamera) {try {} catch (error) {if (error instanceof NotAllowedError) {// 处理错误,然后取消导航return false} else {// 意料之外的错误,取消导航并把错误传给全局处理器throw error}}}
})

router.beforeResolve 是获取数据或执行任何其他操作(如果用户无法进入页面时你希望避免执行的操作)的理想位置。

组件内的守卫

组件内的守卫分为三种:

beforeRouteEnter:在渲染该组件的对应路由被验证前调用 ,当守卫执行时,组件实例还没被创建!

注意:在 vue3 中的 setup 函数中是不可以使用 beforeRouterEnter 这个路由守卫的

方法一、我们可以在设置路由的时候,使用beforeEnter方法拦截,即在router.js中:

{path: '/users/:id',component: UserDetails,beforeEnter: (to, from) => {
// 可以在定义路由的时候监听from和toreturn false},}

方法二、使用选项式api,就可以使用beforeRouterEnter这个钩子了

<script>
export default {beforeRouteEnter(to, from) {console.log('before router enter', to, from)}
}
</script>

beforeRouteUpdate: 在当前路由改变,但是该组件被复用时调用

举例来说,对于一个带有动态参数的路径 `/users/:id`,在 `/users/1` 和 `/users/2` 之间跳转的时候

// 在当前路由改变,但是该组件被复用时调用
// 举例来说,对于一个带有动态参数的路径 `/users/:id`,在 `/users/1` 和 `/users/2` 之间跳转的时候
onBeforeRouteUpdate((to,from)=>{
console.log(from.path,'更新为了',to.path);}

beforeRouteLeave:在导航离开渲染该组件的对应路由时调用

  // 在导航离开渲染该组件的对应路由时调用
onBeforeRouteLeave((to,from)=>{
console.log(from.path,'离开了');})


http://www.ppmy.cn/news/1297853.html

相关文章

jmeter连接数据库

下载jdbc 在浏览器输入 mysql jdbc官网 &#xff1b; 网址&#xff1a;MySQL :: MySQL Connectors 点击 Download 查看自己mysql服务的版本&#xff0c;找到对应版本的jdbc 所以下载5版本的jdbc 安装jdbc&#xff08;绿色版安装&#xff09; 操作jmeter 打开jmeter&#xff0…

Python 架构模式:引言到第四章

引言 原文&#xff1a;Introduction 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 为什么我们的设计会出错&#xff1f; 当你听到混乱这个词时&#xff0c;你会想到什么&#xff1f;也许你会想到喧闹的股票交易所&#xff0c;或者早上的厨房——一切都混乱不堪。当你…

js中对数字,超大金额(千位符,小数点)格式化处理

前言 这个问题的灵感来自线上一个小bug&#xff0c;前两天刚看完同事写的代码&#xff0c;对数字类型处理的很好&#xff0c;之前一直都是用正则和toFixed(2)处理数字相关&#xff0c;后面发现使用numeral.js处理更完美。 对于下面这种数据的处理&#xff0c;你能想到几种方法…

kubernetes volume 数据存储详解

写在前面&#xff1a;如有问题&#xff0c;以你为准&#xff0c; 目前24年应届生&#xff0c;各位大佬轻喷&#xff0c;部分资料与图片来自网络 内容较长&#xff0c;页面右上角目录方便跳转 概述 容器的生命周期可能很短&#xff0c;会被频繁的创建和销毁 保存在容器中的…

滑动窗口协议仿真(2024)

1.题目描述 滑动窗口协议以基于分组的数据传输协议为特征&#xff0c;该协议适用于在数据链路层以及传输层中对按 顺序传送分组的可靠性要求较高的环境。在长管道传输过程&#xff08;特别是无线环境&#xff09;中&#xff0c;相应的滑动窗口 协议可实现高效的重传恢复。附录 …

失败重跑与重复执行插件

章节目录&#xff1a; 一、失败重跑插件1.1 概述1.2 安装1.3 参数讲解1.4 代码示例 二、重复执行插件2.1 概述2.2 安装2.3 代码示例 三、结束语 一、失败重跑插件 1.1 概述 pytest-rerunfailures 是一个用于 pytest 测试框架的插件&#xff0c;它提供了重新运行失败的测试用例…

JavaScript版数据结构与算法(一)栈、队列、链表、集合、树

一、前言 为什么要学习数据结构与算法&#xff1f;最重要的就是面试要考算法&#xff0c;另外就是如果在实际工作当中&#xff0c;能够使用算法优化代码&#xff0c;会提升代码质量和运行效率&#xff0c;作为一名前端人员可能在实际中用的并不是特别多。数据结构与算法是分不…

UG装配-布置

UG装配中&#xff0c;当一个产品在不同情况下具有不同的形态的时候&#xff0c;为了快速进行展示&#xff0c;我们可以使用布置命令. 我们可以直接在工具栏布置中&#xff0c;或者在装配导航器中右键单击装配体&#xff0c;选择布置-编辑&#xff0c;添加不同不同的布置页面 使…