Vue 3.0 中的路由导航守卫详解

news2025/6/2 8:43:30

1. 路由导航守卫

1.1. 全局前置守卫

Vue-Router 提供的导航守卫主要用来守卫路由的跳转或取消。它们可以植入到全局、单个路由或组件级别。

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

const router = createRouter({... });

router.beforeEach((to, from) => {
    // 返回 false 以取消导航
    return false;
});

当导航触发时,全局前置守卫按照创建顺序调用。守卫是异步解析执行,导航会等待所有守卫解析完成后才会继续。

守卫方法参数:

to:即将要进入的目标路由对象。

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

返回值:

false:取消当前导航。如果浏览器的 URL 改变了,URL 会重置到 from 路由对应的地址。

路由地址:重定向到一个不同的地址,如同调用 router.push()。

undefined 或 true:导航有效,继续下一步。

router.beforeEach(async (to, from) => {
    if (!isAuthenticated && to.name !== 'Login') {
        // 将用户重定向到登录页面
        return { name: 'Login' };
    }
});

1.2. 全局解析守卫

全局解析守卫在导航被确认之前调用,可以使用 router.beforeResolve 注册。这适用于获取数据或执行其他操作的场景:

router.beforeResolve(async to => {
    if (to.meta.requiresCamera) {
        try {
            await askForCameraPermission();
        } catch (error) {
            if (error instanceof NotAllowedError) {
                // 处理错误并取消导航
                return false;
            } else {
                // 抛出意料之外的错误并取消导航
                throw error;
            }
        }
    }
});

1.3. 全局后置钩子

全局后置钩子不会改变导航,只执行一些辅助功能,如分析、改变页面标题等:

router.afterEach((to, from) => {
    sendToAnalytics(to.fullPath);
});

1.4. 路由独享守卫

可以在路由配置中直接定义 beforeEnter 守卫,仅在进入路由时触发:

const routes = [
    {
        path: '/users/:id',
        component: UserDetails,
        beforeEnter: (to, from) => {
            // 拒绝导航
            return false;
        },
    },
];

1.5. 组件内的守卫

在路由组件内直接定义守卫,包括 beforeRouteEnter、beforeRouteUpdate 和 beforeRouteLeave:

export default {
    beforeRouteEnter(to, from, next) {
        // 在路由改变前调用,无法访问组件实例
    },
    beforeRouteUpdate(to, from) {
        // 在当前路由改变时调用,实例已挂载
    },
    beforeRouteLeave(to, from) {
        // 在导航离开前调用
    },
};

使用 beforeRouteEnter 守卫访问组件实例,可以通过传递回调给 next:

beforeRouteEnter(to, from, next) {
    next(vm => {
        // 通过 `vm` 访问组件实例
    });
}

1.6. 使用组合 API

如果使用组合式 API,可以通过 onBeforeRouteUpdate 和 onBeforeRouteLeave 添加 update 和 leave 守卫。

2. 完整的导航解析流程

1. 导航被触发;

2. 调用失活组件的 beforeRouteLeave 守卫;

3. 调用全局的 beforeEach 守卫;

4. 调用重用组件的 beforeRouteUpdate 守卫;

5. 调用路由配置中的 beforeEnter;

6. 解析异步路由组件;

7. 调用被激活组件的 beforeRouteEnter 守卫;

8. 调用全局的 beforeResolve 守卫;

9. 导航被确认;

10. 调用全局的 afterEach 钩子;

11. 触发 DOM 更新;

12. 调用 beforeRouteEnter 守卫中传递给 next 的回调函数,访问组件实例;

3. 路由元信息

有时,你可能希望将任意信息附加到路由上,如过渡名称、谁可以访问路由等。这些事情可以通过接收属性对象的meta属性来实现,并且它可以在路由地址和导航守卫上都被访问到。定义路由的时候你可以这样配置 meta 字段:

const routes = [
    {
        path: '/posts',
        component: PostsLayout,
        children: [
            {
                path: 'new',
                component: PostsNew,
                // 只有经过身份验证的用户才能创建帖子
                meta: { requiresAuth: true },
            },
            {
                path: 'id',
                component: PostsDetail,
                // 任何人都可以阅读文章
                meta: { requiresAuth: false },
            }
        ]
    }
];

那么如何访问这个 meta 字段呢?

首先,我们称呼 routes 配置中的每个路由对象为 路由记录。路由记录可以是嵌套的,因此,当一个路由匹配成功后,它可能匹配多个路由记录,匹配成功的路由包括父路由记录以及子路由记录。

一个路由匹配到的所有路由记录会暴露为 route 对象的route.matched 数组。我们需要遍历这个数组来检查路由记录中的 meta 字段,但是 Vue Router 还为你提供了一个 route.meta 方法,它是一个非递归合并所有 meta 字段的方法。这意味着你可以简单地写成:

router.beforeEach((to, from) => {
    // 而不是去检查每条路由记录
    // to.matched.some(record => record.meta.requiresAuth)
    if (to.meta.requiresAuth && !auth.isLoggedIn()) {
        // 此路由需要授权,请检查是否已登录
        // 如果没有,则重定向到登录页面
        return {
            path: '/login',
            // 保存我们所在的位置,以便以后再来
            query: { redirect: to.fullPath },
        }
    }
})

4. 路由懒加载

当打包构建应用时,JavaScript 包含变得非常大,影响页面加载。如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就会更加高效。

Vue Router 支持开箱即用的动态导入,这意味着你可以用动态导入代替静态导入:


// import UserDetails from './views/UserDetails.vue' 
// 将上面的写法换成下面这样

const UserDetails = () => import('./views/UserDetails.vue')

const router = createRouter({

  routes: [

    { path: '/users/:id', component: UserDetails },

    // 或在路由定义里直接使用它
    { path: '/users/:id', component: () => import('./views/UserDetails.vue') }

  ]
})

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2393903.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Sqoop基础】Sqoop生态集成:与HDFS、Hive、HBase等组件的协同关系深度解析

目录 1 Sqoop概述与大数据生态定位 2 Sqoop与HDFS的深度集成 2.1 技术实现原理 2.2 详细工作流程 2.3 性能优化实践 3 Sqoop与Hive的高效协同 3.1 集成架构设计 3.2 数据类型映射处理 3.3 案例演示 4 Sqoop与HBase的实时集成 4.1 数据模型转换挑战 4.2 详细集成流程…

MySQL + CloudCanal + Iceberg + StarRocks 构建全栈数据服务

简述 在业务数据快速膨胀的今天,企业对 低成本存储 与 实时查询分析能力 的需求愈发迫切。 本文将带你实战构建一条 MySQL 到 Iceberg 的数据链路,借助 CloudCanal 快速完成数据迁移与同步,并使用 StarRocks 完成数据查询等操作&#xff0c…

截屏精灵:轻松截屏,高效编辑

在移动互联网时代,截图已经成为我们日常使用手机时的一项基本操作。无论是记录重要信息、分享有趣内容,还是进行学习和工作,一款好用的截图工具都能极大地提升我们的效率。截屏精灵就是这样一款功能强大、操作简单的截图工具,它不…

【JavaWeb】基本概念、web服务器、Tomcat、HTTP协议

目录 1. 基本概念1.1 基本概念1.2 web应用程序1.3 静态web1.4 动态web 2. web服务器3. tomcat详解3.1 安装3.2 启动3.3 配置3.3.1 配置启动的端口号3.3.2 配置主机的名称3.3.3 其他常用配置项日志配置数据源配置安全配置 3.4 发布一个网站 4. Http协议4.1 什么是http4.2 http的…

云计算Linux Rocky day02(安装Linux系统、设备表示方式、Linux基本操作)

云计算Linux Rocky day02(安装Linux系统、设备表示方式、Linux基本操作) 目录 云计算Linux Rocky day02(安装Linux系统、设备表示方式、Linux基本操作)1、虚拟机VMware安装Rocky2、Linux命令行3、Linux Rocky修改字体大小和背景颜…

在 ODROID-H3+ 上安装 Win11 系统

在 ODROID-H3 上安装 Windows 11 系统。 以下是完整的步骤,包括 BIOS 设置、U 盘制作、安装和驱动处理,全程不保留之前的系统数据。 ✅ 准备工作 1. 准备一个 ≥8GB 的 USB 启动盘 用另一台电脑制作 Windows 11 安装盘。 👉 推荐工具&…

使用el-input数字校验,输入汉字之后校验取消不掉

先说说复现方式 本来input是只能输入数字的&#xff0c;然后你不小心输入了汉字&#xff0c;触发校验了&#xff0c;然后这时候&#xff0c;你发现校验取消不掉了 就这样了 咋办啊&#xff0c;你一看校验没错啊&#xff0c;各种number啥的也写了,发现没问题啊 <el-inputv…

Docker容器启动失败的常见原因分析

我们在开发部署的时候&#xff0c;用 Docker 打包环境&#xff0c;理论上是“我装好了你就能跑”。但理想很丰满&#xff0c;现实往往一 docker run 下去就翻车了。 今天来盘点一下我实际工作中经常遇到的 Docker 容器启动失败的常见原因&#xff0c;顺便给点 debug 的小技巧&a…

立志成为一名优秀测试开发工程师(第七天)——unittest框架的学习

目录 unittest框架的学习 一、测试类的编写 创建相关测试类cal.py、CountTest.py 二、常见断言方法 使用unittest单元测试框架编写测试用例CountTest.py 注意&#xff1a;执行的时候光标一定要放在括号后面&#xff0c;鼠标右键运行 三、对测试环境的初始化和清除模块…

论坛系统(4)

用户详情 获取用户信息 实现逻辑 ⽤⼾提交请求&#xff0c;服务器根据是否传⼊Id参数决定返回哪个⽤⼾的详情 1. 不传⽤⼾Id&#xff0c;返回当前登录⽤⼾的详情(从session获取) 2. 传⼊⽤⼾Id&#xff0c;返回指定Id的⽤⼾详情(根据用户id去查) 俩种方式获得用户信息 参…

力扣面试150题--二叉树的层平均值

Day 54 题目描述 思路 初次做法&#xff08;笨&#xff09;&#xff1a;使用两个队列&#xff0c;一个队列存放树的节点&#xff0c;一个队列存放对应节点的高度&#xff0c;使用x存放上一个节点&#xff0c;highb存放上一个节点的高度&#xff0c;sum存放当前层的节点值之和…

【Doris入门】Doris初识:分布式分析型数据库的核心价值与架构解析

目录 1 Doris简介与核心价值 2 Doris架构深度解析 2.1 Frontend&#xff08;FE&#xff09;架构 2.2 Backend&#xff08;BE&#xff09;架构 3 Doris核心概念详解 3.1 数据分布模型 3.2 Tablet与Replica 3.3 数据模型 4 Doris关键技术解析 4.1 存储引擎 4.2 查询执…

数据结构与算法学习笔记(Acwing 提高课)----动态规划·区间DP

数据结构与算法学习笔记----动态规划区间DP author: 明月清了个风 first publish time: 2025.5.26 ps⭐️区间DP的特征在于子结构一般是一个子区间上的问题&#xff0c;涉及到的问题也非常多&#xff0c;如环形区间&#xff0c;记录方案数&#xff0c;高精度&#xff0c;二维…

从0到1搭建AI绘画模型:Stable Diffusion微调全流程避坑指南

从0到1搭建AI绘画模型&#xff1a;Stable Diffusion微调全流程避坑指南 系统化学习人工智能网站&#xff08;收藏&#xff09;&#xff1a;https://www.captainbed.cn/flu 文章目录 从0到1搭建AI绘画模型&#xff1a;Stable Diffusion微调全流程避坑指南摘要引言一、数据集构…

从一到无穷大 #46:探讨时序数据库Deduplicate与Compaction的设计权衡

本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。 本作品 (李兆龙 博文, 由 李兆龙 创作)&#xff0c;由 李兆龙 确认&#xff0c;转载请注明版权。 文章目录 引言Compaction AlgorithmsCompact Execution Flow Based On VeloxLocalMergeSource的…

vue3 导出excel

需求&#xff1a;导出自带格式的excel表格 1.自定义二维数组格式 导出 全部代码&#xff1a; <el-button click"exportExcel">导出</el-button> const exportExcel () > {const data [[商品, 单价, 数量, 总价],[A, 100, 1.55, { t: n, f: B2*C2…

day024-网络基础-TCP与UDP、DNS

文章目录 1. 李导推荐书籍2. OSI七层模型2.1 传输层2.2 网络层2.2.1 问&#xff1a;两端处于不同局域网的设备怎么网络通信&#xff1f; 2.3 数据链路层2.4 物理层2.5 图解OSI七层模型 3. 数据传输模式3.1 全双工3.2 半双工3.3 单工 4. TCP 3次握手4.1 抓包 5. TCP 4次挥手5.1 …

专场回顾 | 重新定义交互,智能硬件的未来设计

自2022年起&#xff0c;中国智能硬件行业呈现出蓬勃发展的态势&#xff0c;市场规模不断扩大。一个多月前&#xff0c;“小智AI”在短视频平台的爆火将智能硬件带向了大众视野&#xff0c;也意味着智能硬件已不再仅仅停留在概念和技术层面&#xff0c;而是加速迈向实际落地应用…

WPS 免登录解锁编辑

遇到 WPS 需要登录才能启用编辑功能&#xff1f; 如何免登录使用编辑功能&#xff1f; 方法一 解锁方法 1、关闭 WPS&#xff1b; 2、桌面右键→ “新建”→“文本文档”&#xff0c;粘贴以下内容&#xff08;见最下面&#xff09;&#xff1b;编码保持默认&#xff08;ANSI …

技术分享 | Oracle SQL优化案例一则

本文为墨天轮数据库管理服务团队第70期技术分享&#xff0c;内容原创&#xff0c;作者为技术顾问马奕璇&#xff0c;如需转载请联系小墨&#xff08;VX&#xff1a;modb666&#xff09;并注明来源。 一、问题概述 开发人员反映有条跑批语句在测试环境执行了很久都没结束&…