从Vue2 到 Vue3,这些路由差异你需要掌握!
✨ 个人主页:山山而川~xyj
⚶ 作者简介:前端领域新星创作者,专注于前端各领域技术,共同学习共同进步,一起加油!
🎆 系列专栏: vue系列
🚀 学习格言:与其临渊羡鱼,不如退而结网
目录
- 前言
- 一、导航守卫
- 全局前置守卫
- 全局解析守卫
- 全局后置钩子
 
- 二、路由模式
- 三、路由组件传参
- 布尔模式
- 命名视图
- 对象模式
- 函数模式
 
- 四、滚动行为
- 滚动到固定距离
- 滚动到元素位置
- 滚动到锚点位置
- 滚动到之前的位置
- 延迟滚动
 
- 五、过渡动效
- 基本用法
- 单个路由的过渡
- 复用的组件之间进行过渡
 
- 六、动态路由
- 添加路由
- 删除路由
- 添加嵌套路由
 
- 结论
前言
Vue3已经出来很长时间了,但对Vue3的路由却了解的非常少,甚至只知道最基本的跳转和参数获取,这些技能处理一些复杂的功能是不够的,最近把Vue3的路由版本差异给学习了一下,在这里把结果分享给大家!!!
一、导航守卫
全局前置守卫
全局前置守卫通常用来做权限控制,使用 router.beforeEach 即可添加:
const router = createRouter({...})
router.beforeEach((to, from) => {// ...// 返回 false 取消导航return false;
})
每个守卫方法接收两个参数:
- to::即将进入的目标路由
- from:当前正要离开的路由
 返回值可以是以下值:
- false:取消当前导航
- true | undefined:调用下一个守卫
- 一个路由地址:字符串或对象。表示中断当前导航,进行下一个新的导航
router.beforeEach(async(to, from) => {// 检查用户是否已经登录if (!isAuthenticated  && to.name !== 'Login) {return { name: 'Login' }}
})
注意:在全局前置守卫中,要确保 next 在导航守卫中只被调用一次。
全局解析守卫
router.beforeResolve 用法和 router.beforeEach 类似。它是在导航被确认之前,所有组件内守卫和异步路由组件被解析之后被调用。
router.beforeResolve(async to => {if (to.meta.requiresCamera) {try {await askForCameraPermission()} catch (error) {if (error instanceof NotAllowedError) {// 处理错误,然后取消导航return false} else {// 取消导航并把错误传给全局处理器throw error}}}
})
上面这个例子,是为了确保用户可以访问自定义 meta 属性。
全局后置钩子
router.afterEach 和守卫不通,全局后置钩子不接受 next 函数,也不能跳转到其他的路由地址。但是它对于访问分析、更改页面标题、生命页面等辅助功能很有帮助。
router.afterEach((to, from) => {sendTo(to.fullPath)
})
二、路由模式
Vue3 中不再使用 new Router() 创建 router,而是调用 createRouter 方法:
import { createRouter } from 'vue-router'const router = createRouter({// ...
})
路由模式 mode 配置为 history,属性值调整为:
- ‘history’ => createWebHistory()
-  - ‘hash’ => createWebHashHistory()
 
- ‘hash’ => 
-  - ‘abstract’ => createMemoryHistory()
 
- ‘abstract’ => 
import { createRouter, createWebHistory } from 'vue-router'
// createWebHashHistory 和 createMemoryHistory (SSR相关) 同理createRouter({history: createWebHistory(),routes: []
})
基础路径 base 被作为 createWebHistory 的第一个参数进行传递(其他路由模式也是一样):
import { createRouter, createWebHistory } from 'vue-router'
createRouter({history: createWebHistory('/base-url/'),routes: []
})
三、路由组件传参
当我们获取路由参数时,通常在模板中使用 $route,在逻辑中调用 useRoute() 方法,如:
<template><div>User {{ $route.params.id }}</div>
</template><script setup lang="ts">
import { useRoute } from 'vue-router'
const route = useRoute()
console.log(route.params.id)
</script>
以上方法比较麻烦,而且与路由紧密耦合,不利于组件封装。我们可以在创建路由时通过 props 配置来解除这种行为:
const routes = [{path: '/user/:id',name: 'user',component: User,props: true}
]
此时 route.params 将直接被设置为组件的 props,这样组件就和路由参数解耦了:
<template><div>User {{ id }}</div>
</template><script setup lang="ts">
const props = defineProps<{id: string
}>()
console.log(props.id)
</script>
布尔模式
当 props 设置为 true 时,route.params 将被设置为组件的 props。
命名视图
对于有命名视图的路由,你必须为每个命名视图定义 props 配置:
const routes = [{path: '/user/:id',components: { default: User, sidebar: Sidebar },props: { default: true, sidebar: false }}
]
对象模式
当 props 是一个对象时,它会将此对象设置为组件 props 。当 props 是静态的时候很有用。
const routes = [{path: '/user',component: User,props: { newsletterPopup: false }}
]
函数模式
我们也可以创建一个返回 props 的函数。这允许你将参数转换为其他类型:
const routes = [{path: '/user',component: User,props: route => ({ id: route.query.id })}
]
如 /user?id=123 参数会被转为 { id: '123' } 作为 props 传给组件。
四、滚动行为
我们可以通过 vue-router 自定义路由切换时页面如何滚动。比如,当跳转到新路由时,页面滚动到某个位置;切换路由时页面回到之前的滚动位置。
 当创建路由实例时,我们只需要提供一个 scrollBehavior 方法:
const router = createRouter({history: createWebHashHistory(),routes: [...],scrollBehavior (to, from, savedPosition) {// return 期望滚动到哪个的位置}
})
scrollBehavior 函数接收 to 和 from 路由对象。第三个参数 savedPosition,只有当这是一个 popstate 导航时才可用(点击浏览器的后退/前进按钮,或者调用 router.go() 方法)
滚动到固定距离
该函数可以返回一个 ScrollToOptions 位置对象:
const router = createRouter({scrollBehavior(to, from, savedPosition) {// 始终滚动到顶部return { top: 0 }},
})
滚动到元素位置
可以通过 el 传递一个 CSS 选择器或一个 DOM 元素。在这种情况下,top 和 left 将被视为该元素的相对偏移量。
const router = createRouter({scrollBehavior(to, from, savedPosition) {// 始终在元素 #main 上方滚动 10pxreturn {// el: document.getElementById('main'),el: '#main',top: -10,}},
})
滚动到锚点位置
const router = createRouter({scrollBehavior(to, from, savedPosition) {if (to.hash) {return {el: to.hash,}}},
})
滚动到之前的位置
在按下浏览器 后退/前进 按钮,或者调用 router.go() 方法时,页面会回到之前的滚动位置:
const router = createRouter({scrollBehavior(to, from, savedPosition) {if (savedPosition) {return savedPosition} else {return { top: 0 }}},
})
注意:如果返回一个 false 的值,或者是一个空对象,则不会发生滚动。我们还可以在返回的对象中添加 behavior: 'smooth' ,让滚动更加丝滑。
延迟滚动
有时候我们不希望立即执行滚动行为。例如当页面做了过渡动效,我们希望过渡结束后再执行滚动。要做到这一点,我们可以返回一个 Promise:
const router = createRouter({scrollBehavior(to, from, savedPosition) {return new Promise((resolve, reject) => {setTimeout(() => {resolve({ left: 0, top: 0 })}, 500)})}
})
五、过渡动效
基本用法
如果想要在路由组件上使用转场,对导航进行动画处理,我可以使用 v-slot 结合 Animete.css 来实现:
<RouterView v-slot="{ Component }"><transition enter-active-class="animate__animated animate__fadeIn"><component :is="Component" /></transition>
</RouterView>
单个路由的过渡
上面的用法会对所有的路由使用相同的过渡。如果你想让每个路由的组件有不同的过渡,可以将 元信息 和动态的 enter-active-class 结合在一起,放在 <transition> 上:
// js
const routes = [{path: '/home',component: Home,meta: { transition: 'animate__fadeIn' },},{path: '/user',component: User,meta: { transition: 'animate__bounceIn' },},
]
// vue
<RouterView v-slot="{ Component }"><transition :enter-active-class="`animate__animated ${$route.meta.transition}`"><component :is="Component" /></transition>
</RouterView>
复用的组件之间进行过渡
const routes = [{path: '/user/:id',component: User,meta: { transition: 'animate__bounceIn' },},
]
定义以上路由,当从 /user/123 切换到 /user/456 时是没有任何过渡效果的。这时候我们可以添加一个 key 属性来强制进行过渡,key 值只要不同就行了。说白了就是让 Dom 不要被复用,和 v-for 的 key 属性原理刚好相反。
<router-view v-slot="{ Component, route }"><transition :enter-active-class="`animate__animated ${$route.meta.transition}`"><component :is="Component" :key="route.path" /></transition>
</router-view>
六、动态路由
添加路由
当我们做用户权限的时候,添加路由非常有用。可以使用 router.addRoute() 来添加一个路由:
router.addRoute({ path: '/about', name: 'about', component: About })
注意:跟之前版本不同的是,路由只能一个一个添加,不能批量添加。
删除路由
以下几个方法都可以删除路由:
- 通过使用 router.removeRoute()按名称删除路由:
router.addRoute({ path: '/about', name: 'about', component: About })
// 删除路由
router.removeRoute('about')
- 通过添加一个名称相同的路由,替换掉之前的路由:
router.addRoute({ path: '/about', name: 'about', component: About })
// 这将会删除之前已经添加的路由,因为他们具有相同的名字且名字必须是唯一的
router.addRoute({ path: '/other', name: 'about', component: Other })
- 通过调用 router.addRoute()返回的回调函数:
const removeRoute = router.addRoute(routeRecord)
removeRoute() // 删除路由如果存在的话
当路由没有名称时,这种方法非常有用。
添加嵌套路由
要将嵌套路由添加到现有的路由中,可以将路由的 name 作为第一个参数传递给 router.addRoute() ,这和通过 children 添加的效果一样:
router.addRoute({ name: 'admin', path: '/admin', component: Admin })
// 添加嵌套路由
router.addRoute('admin', { path: 'settings', component: AdminSettings })
相当于:
router.addRoute({name: 'admin',path: '/admin',component: Admin,children: [{ path: 'settings', component: AdminSettings }]
})
结论
本片文章大部分来自官网,也有一些来自自己的实践心得。希望对你的开发工作有所帮助。当然这并不是 Vue-Router4 的所有内容,比如还有路由匹配、重定向和别名等等,大家可以自行在官网查看。如果今天的分享对你有所帮助,不要忘记三连呦🌹
相关文章:
从Vue2 到 Vue3,这些路由差异你需要掌握!
✨ 个人主页:山山而川~xyj ⚶ 作者简介:前端领域新星创作者,专注于前端各领域技术,共同学习共同进步,一起加油! 🎆 系列专栏: vue系列 🚀 学习格言:与其临渊羡…...
 
Maxwell简介、部署、原理和使用介绍
Maxwell简介、部署、原理和使用介绍 1.Maxwell概述简介 1-1.Maxwell简介  Maxwell是由美国Zendesk公司开源,使用Java编写的MySQL变更数据抓取软件。他会实时监控Mysql数据库的数据变更操作(包括insert、update、delete),并将变…...
20230215_数据库过程_渠道业务清算过程
----2023-0131-清算过程 zhyw.shc_drop_retable(upper(‘xc_qdcn_pgtx_qsqdtype_sja’),‘SHZC’); SQL_STRING:‘create table shzc.xc_qdcn_pgtx_qsqdtype_sja as select * from shzc.xc_qdcn_pgtx_qdtype a where a.in_time ( select max(a.in_time) from shzc.xc_qdcn_pg…...
 
webpack(高级)--性能优化-代码分离
webpack webpack性能优化 优化一:打包后的结果 上线时的性能优化 (比如分包处理 减少包体积 CDN服务器) 优化二:优化打包速度 开发或者构建优化打包速度 (比如exclude cache-loader等) 大多数情况下我们侧…...
 
借助docker, 使用verdaccio搭建npm私服
为何要搭建npm私服 搭建npm私服好处多多,网上随便一篇教程搜出来都罗列了诸多好处,譬如: 公司内部开发环境与外网隔离,内部开发的一些库高度隐私不便外传,内网搭建npm服务保证私密性同属内网,可以确保使用npm下载依赖…...
 
c/c++开发,无可避免的模板编程实践(篇二)
一、开发者需要对模板参数负责 1.1 为您模板参数提供匹配的操作 在进行模板设计时,函数模板或类模板一般只做模板参数(typename T)无关的操作为主,但是也不见得就不会关联模板参数自身的操作,尤其是在一些自定义的数据…...
 
【2023】【standard-products项目】中查找的问题与解决方案 (未完待续)
10、el-table 判断是多选操作还是单选操作 9、判断数组对象中是否包含某个指定值 需求:修改时数据回填el-select下拉数据,发现当前id在原数组里没有找到,就显示了id值,应该显示name名, 处理:当查找到id…...
 
力扣sql简单篇练习(十六)
力扣sql简单篇练习(十六) 1 产品销售分析|| 1.1 题目内容 1.1.1 基本题目信息 1.1.2 示例输入输出 1.2 示例sql语句 SELECT p.product_id,sum(s.quantity) total_quantity FROM Product p INNER JOIN Sales s ON p.product_ids.product_id GROUP BY p.product_id1.3 运行截…...
青少年蓝桥杯python组(STEMA中级组)
第一套编程题第一题【编程实现】输入一个字符串(N),输出该字符串的长度。输入描述:输入一个字符串 N输出描述:输出该字符串的长度【样例输入】abcd【样例输出】4N input() print(len(N))第二题【提示信息】小蓝家的灯…...
 
JVM内存结构,Java内存模型,Java对象模型
一.整体方向JVM内存结构是和java虚拟机的运行时区域有关。Java内存模型和java并发编程有关。java对象模型和java对象在虚拟机中的表现形式有关。1.JVM内存结构堆:通过new或者其他指令创建的实例对象,会被垃圾回收。动态分配。虚拟机栈:基本数…...
 
跨境电商新形式下,如何选择市场?
2022年,全球经济已经有增长乏力、通胀高起的趋势,美国等国家的通货膨胀情况令人担忧,不少行业面临更为复杂的外部环境以及严峻的市场挑战。不过,跨境电商行业依旧保持着较高的增长速度,越来越多有远见的卖家将电商事业…...
 
MySQL的触发器
目录 一.概述 介绍 触发器的特性 操作—创建触发器 操作—new和old 操作—查看触发器 操作—删除触发器 注意事项 一.概述 介绍 触发器,就是一种特殊的存储过程。触发器和存储过程一样是一个能够完成特定功能、存储在数据库服务器上的SQL片段,但是…...
内存映射模块读写文件提高IO性能mmap
内存映射模块读写文件提高IO性能mmap 1.概述 这篇文章介绍下与普通读写文件不同的方式,内存映射读写文件。在什么情况下才会用到内存映射操作文件那,还是要先了解下他。 1.1.内存映射与IO区别 常规操作IO开销 常规的操作文件是经过下面几个环节操作I…...
 
存储硬件与协议
存储硬件与协议存储设备的历史轨迹存储介质的进化3D NAND3D XPointIntel Optane存储接口协议的演变NVMeNVMe-oF网络存储技术1)DAS2)NAS3)SAN4)iSCSIiSCSI层次结构存储设备的历史轨迹 1.穿孔卡2.磁带3.硬盘4.磁盘(软盘…...
智能物流半导体发展
智能物流半导体在国内的发展,国内巨大的人口基数,这将会不断促进智慧物流的发展。智能物流在未来发展的潜力巨大。 关于触屏的设计是界面越简单,越清晰越好,最近设计一个小车控制触屏软件。把小车当前所在信息通过图像显示出来。…...
 
SAP S/4HANA 概述
智能企业业务技术平台Business Technology Platform提供数据管理和分析,并支持应用程序开发和集成。它还允许我们的客户使用人工智能、机器学习和物联网等智能技术来推动创新。业务网络Business network帮助客户实现跨公司业务流程的数字化。该网络建立在我们的采购…...
太上感应篇
太上感应篇原文 太上曰。祸福无门。惟人自召。善恶之报。如影随形。 是以天地有司过之神。依人所犯轻重。以夺人算。算减则贫耗。多逢忧患。人皆恶之。刑祸随之。吉庆避之。恶星灾之。算尽则死。 又有三台北斗神君。在人头上。录人罪恶。夺其纪算。又有三尸神。在人身中。每…...
 
FPGA入门系列17--task
文章简介 本系列文章主要针对FPGA初学者编写,包括FPGA的模块书写、基础语法、状态机、RAM、UART、SPI、VGA、以及功能验证等。将每一个知识点作为一个章节进行讲解,旨在更快速的提升初学者在FPGA开发方面的能力,每一个章节中都有针对性的代码…...
 
React学习笔记(番外二)——列表多选批量处理复合组件
React学习笔记(番外二)——列表多选批量操作复合组件前言〇、Show you the code一、 任务分析及拆解表头行的Checkbox——总开关记录行的Checkbox——行级开关二、 基础实现表头行的文件——header-row.js记录行的文件——record-row.js页面的文件App.js…...
 
Pom.xml详解
目录 1、Maven的下载安装 2、什么是pom? 3、较完整的pom元素 4、默认生成Maven工程的pom内容 5、自定义的属性变量 6、依赖管理 6.1、整体依赖关系列表 6.2、依赖关系的传递性 6.3、依赖传递可能造成的问题 6.3.1、scope依赖范围 6.3.2、依赖调节 6.3.3…...
 
AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...
 
地震勘探——干扰波识别、井中地震时距曲线特点
目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波:可以用来解决所提出的地质任务的波;干扰波:所有妨碍辨认、追踪有效波的其他波。 地震勘探中,有效波和干扰波是相对的。例如,在反射波…...
逻辑回归:给不确定性划界的分类大师
想象你是一名医生。面对患者的检查报告(肿瘤大小、血液指标),你需要做出一个**决定性判断**:恶性还是良性?这种“非黑即白”的抉择,正是**逻辑回归(Logistic Regression)** 的战场&a…...
 
定时器任务——若依源码分析
分析util包下面的工具类schedule utils: ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类,封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz,先构建任务的 JobD…...
c++ 面试题(1)-----深度优先搜索(DFS)实现
操作系统:ubuntu22.04 IDE:Visual Studio Code 编程语言:C11 题目描述 地上有一个 m 行 n 列的方格,从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子,但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...
vue3 定时器-定义全局方法 vue+ts
1.创建ts文件 路径:src/utils/timer.ts 完整代码: import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...
【git】把本地更改提交远程新分支feature_g
创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...
Swagger和OpenApi的前世今生
Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章,二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑: 🔄 一、起源与初创期:Swagger的诞生(2010-2014) 核心…...
 
python执行测试用例,allure报乱码且未成功生成报告
allure执行测试用例时显示乱码:‘allure’ �����ڲ����ⲿ���Ҳ���ǿ�&am…...
 
Springboot社区养老保险系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,社区养老保险系统小程序被用户普遍使用,为方…...
