【Vue3 生态】VueRouter 路由核心知识点
1. 动态路由
1.1 动态路由匹配
路由分为静态路由和动态路由。上面讲过的类似 ‘/login’ 这样写死的就是静态路由。
动态路由通过在路径中使用一个动态字段(简称:路径参数),来将不同的信息映射到同一个组件中。
如:有一个 User 组件用于渲染所有用户,但这些用户的 ID 是不同的
# User.vue
<script setup>import { useRouter } from 'vue-router'const router = useRouter()console.log(router.params)
</script>
<template><div>{{ $route.params.id }}</div>
</template>
import { createRouter, createWebHistory } from 'vue-router'import Login from '@/views/Login.vue'const routes = [{path: '/',redirect: '/Login'},{path: '/login',name: 'login',component: Login,meta: {title: '登录',requiresAuth: false // 设置为 false 或 不设置代表不需要校验身份,任何人都可以访问这个页面}},{path: '/user/:id',name: 'user',component: () => import('@/views/User.vue'),meta: {title: '用户管理', // 页面标题requiresAuth: true // 登录身份校验成功,才可以访问这个页面}}
]const router = createRouter({history: createWebHistory(import.meta.env.BASE_URL),routes
})router.beforeEach((to, from) => {if(to.meta.title) document.title = to.meta.title
})export default router
- meta 路由元信息:可用于给路由附加如:过渡名称、访问路由权限、页面标题等任意信息。可以通过路由地址或导航守卫进行访问。
- router.beforeEach((to,from) => {}) 注册一个全局前置守卫,它会在每次导航之前被执行。
- to 即将要进入的目标
- from 当前导航正要离开的路由
- 路径参数用冒号
:
表示。当一个路由被匹配时,它的 params 值将在每个组件中以$route.params
的形式暴露出来。
1.2 动态路由另外一种配置方式
可以通过 children 配置动态参数
const routes = [// ...其它路由参数{path: '/user',name: 'user',children: [{path: ':id',component: () => import('@/views/User.vue'),meta: {title: '用户管理',requiresAuth: true},},{path: 'Add',component: () => import('@/views/UserAdd.vue'),meta: {title: '用户新增',requiresAuth: true}}]}
]
- 以
/
开头的嵌套路径将被视为根路径。这允许你利用组件嵌套,而不必使用嵌套的 URL。
1.3 路由的匹配语法——在参数中自定义正则
两个路由 /:orderId
和 /:productName
,两者会匹配完全相同的 URL,所以我们需要一种方法来区分它们。
假设:orderId
总是一个数字,而 productName
可以是任何东西,所以我们可以在括号中为参数指定一个自定义的正则
const routes = [// /:orderId -> 仅匹配数字{ path: '/:orderId(\\d+)' },// /:productName -> 匹配其他任何内容{ path: '/:productName' },
]
这时,跳转到 /25
将匹配 /:orderId
,其他情况将会匹配 /:productName
。
确保转义反斜杠( \
),就像我们对 \d
(变成\\d
)所做的那样,在 JavaScript 中实际传递字符串中的反斜杠字符。
更多路由匹配语法详见 Vue Router 官网。
1.4 对路由的增删改操作API
对路由的添加通常是通过 routes
选项 来完成的,但是在某些情况下,你可能想在应用程序已经运行的时候添加或删除路由:
- 添加路由 router.addRoute()
- 移除路由 router.removeRoute()
// 添加路由
router.addRoute({ path: '/about', component: About })
// 我们也可以使用 this.$route 或 route = useRoute() (在 setup 中)
router.replace(router.currentRoute.value.fullPath)
// 删除路由
router.removeRoute('about')
如果你需要等待新的路由显示,可以使用
await router.replace()
2. 命名视图
如果想在同一个界面中定义多个同级视图,就需要给 router-view
设置名字(默认 default),这样就可以有多个出口了。
<router-view class="view left-sidebar" name="LeftSidebar"></router-view>
<router-view class="view main-content"></router-view>
<router-view class="view right-sidebar" name="RightSidebar"></router-view>
一个视图使用一个组件渲染,因此对于同个路由,多个视图就需要多个组件。确保正确使用 components
配置 (带上 s):
const router = createRouter({history: createWebHashHistory(),routes: [{path: '/',components: {default: Home,// LeftSidebar: LeftSidebar 的缩写LeftSidebar,// 它们与 `<router-view>` 上的 `name` 属性匹配RightSidebar,},},],
})
更高级的嵌套命名视图如下,可以尝试着自己分析写一下代码:
/settings/emails /settings/profile
+-----------------------------------+ +------------------------------+
| UserSettings | | UserSettings |
| +-----+-------------------------+ | | +-----+--------------------+ |
| | Nav | UserEmailsSubscriptions | | +------------> | | Nav | UserProfile | |
| | +-------------------------+ | | | +--------------------+ |
| | | | | | | | UserProfilePreview | |
| +-----+-------------------------+ | | +-----+--------------------+ |
+-----------------------------------+ +------------------------------+
Nav
只是一个常规组件。UserSettings
是一个视图组件。UserEmailsSubscriptions
、UserProfile
、UserProfilePreview
是嵌套的视图组件。
3 路由组件传参
带路由的项目组件中,使用 $route 会与路由紧密耦合,这限制了组件的灵活性,使得它只能用于特定的 URL。
如果想要解除这种行为,可以通过 props 进行配置
3.1 路由 props 属性值为 true
# 路由配置代码
{path: '/user',name: 'user',component: () => import('@/views/User.vue'),children: [{ path: ':id',component: () => import('@/views/UserHome.vue'),// 路由配置 props:true,这样映射的组件中可以通过 props 定义对应的路由参数,从而达到$route对象和组件解耦的效果props: true}]
}
# 路由映射组件代码
<script setup>import { defineProps } from 'vue'import { useRouter } from 'vue-router'const router = useRouter()// 组件 props 中定义路由参数对应的属性const props = defineProps(['id'])
</script>
<template><div>// 通过 $route 对象调用路由参数<em> {{ $route.params.id }} </em><br>// 通过 props 中定义的属性调用路由参数<strong>{{ props.id }}</strong></div>
</template>
- 当路由配置属性
props
设置为true
时,route.params
将被设置为组件的 props- 路由组件传参的好处是:使组件更容易重用和测试。
如果路由中含有命名视图,那么你必须为每个命名视图定义 props 配置:
const routes = [{path: '/user/:id',components: { default: User, sidebar: Sidebar },props: { default: true, sidebar: false }}
]
3.2 路由 props 属性值为一个普通对象
当 props
是一个对象时,它将原样设置为组件 props。当 props 是静态的时候很有用。
# 路由代码
{path: '/user',name: 'user',component: () => import('@/views/User.vue'),children: [{ path: ':id',component: () => import('@/views/UserHome.vue'),// props 是一个对象,会将这个对象传递给对应的组件。props 中无法获取路由参数props: { num: 1234567890 }}]
}
# 映射组件的代码
<script setup>import { defineProps } from 'vue'const props = defineProps(['id', 'num'])console.log(props, 11111111111) //Proxy(Object) {num: 1234567890, id: undefined} 11111111111
</script>
<template><div><em> {{ $route.params.id }} </em><br><strong>{{ props.id }}</strong> <!-- props 中无法获取路由参数 --><hr><ins>{{ props.num }}</ins></div>
</template>
3.4 路由 props 属性值为一个函数
你可以创建一个返回 props 的函数。这允许你将参数转换为其他类型,将静态值与基于路由的值相结合等等。
const routes = [{path: '/search',component: SearchUser,props: route => ({ query: route.query.q })}
]
URL /search?q=vue
将传递 {query: 'vue'}
作为 props 传给 SearchUser
组件。
4. history 历史模式
在创建路由器实例时,history
配置允许我们在不同的历史模式中进行选择。
-
Hash 模式
hash 模式是用
createWebHashHistory()
创建的,不依赖于服务器配置。但不会被搜索引擎处理,SEO效果较差。import { createRouter, createWebHashHistory } from 'vue-router'const router = createRouter({history: createWebHashHistory(),routes: [//...], })
createWebHashHistory(base?)
参数为一个路径// 基于 https://example.com/folder 的 hash 模式 createWebHashHistory() // 给出一个 `https://example.com/folder#` 的 URL createWebHashHistory('/folder/') // 给出一个 `https://example.com/folder/#` 的 URL
-
HTML5 模式
HTML5 模式使用
createWebHistory()
创建 ,需要正确的配置服务器。这种方式会被搜索引擎处理,SEO效果较好。是单页应用最常见的模式。如果 URL 不匹配任何静态资源,它应提供与你的应用程序中的
index.html
相同的页面。各服务器配置示例import { createRouter, createWebHistory } from 'vue-router' const router = createRouter({history: createWebHistory(),routes: [//...] })
当使用这种历史模式时,URL 会看起来很 “正常”,例如
https://example.com/user/id
。
万能路由显示 404 页面:
const router = createRouter({history: createHistory(),routes: [{ path: '/:pathMatch(.*)', component: NotFoundComponent }]
})
5 路由守卫
Vue Router 提供了多种路由守卫,如:全局路由守卫、组件内路由守卫或单个路由独享守卫。它们主要通过跳转或取消的方式守卫导航。
5.1 全局前置守卫
全局前置守卫通过 router.beforeEach(callback(to, from)) 注册。参数是一个守卫方法,其接收两个参数:
- to 即将要进入的目标
- from 当前导航正要离开的路由
当一个导航触发时,全局前置守卫按照创建顺序调用。守卫异步解析执行,此时导航在所有守卫 resolve 完之前一直处于等待中。
可以返回的值:
-
false:用于取消当前导航。
const router = createRouter({ ... })router.beforeEach((to, from) => {// ...// 返回 false 以取消导航return false })
-
一个路由地址:如同调用 router.push() 一样,可以跳转到这个指定的路由地址,可以在返回对象中通过如:replace:true 或 name: ‘home’ 之类的属性来指定这个路由地址。
router.beforeEach(async (to, from) => {if (// 检查用户是否已登录!isAuthenticated &&// 避免无限重定向to.name != 'Login') {// 将用户重定向到登录页面return { name: 'Login' }} })
router.beforeEach(async (to, from) => {// canUserAccess() 返回 `true` 或 `false`const canAccess = await canUserAccess(to)if (!canAccess) return '/login' })
5.2 全局解析守卫
全局解析守卫通过 router.beforeResolve 注册。解析守卫刚好会在每次导航被确认之前、所有组件内守卫和异步路由组件被解析之后调用。
5.3 全局后置钩子
后置钩子不会改变导航本身。对于分析、更改页面标题、声明页面等辅助功能以及许多其它事情很有用。
5.4 路由独享守卫
beforeEnter 守卫可直接在路由上进行配置,只在进入路由时触发。而 params、query、hash 改变时不会触发。
const routes = [{path: '/users/:id',component: UserDetails,beforeEnter: (to, from) => {// 返回 false 用于取消当前导航return false}}
]
beforeEnter 守卫也可以是一个函数数组。
5.5 组件内守卫
顾名思义,就是在组件内直接定义路由导航守卫,会传递给路由配置。
路由组件可以添加如下守卫(setup 组合式 API):
-
onBeforeRouteUpdate 在当前路由改变且该组件被复用时调用。
举例来说,对于一个带有动态参数的路径
/users/:id
,在/users/1
和/users/2
之间跳转的时候,由于会渲染同样的UserDetails
组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。 -
onBeforeRouteLeave 在导航离开渲染组件对应的路由时调用。
这个 离开守卫 通常用来预防用户在还未保存修改前突然离开。该导航可以通过返回
false
来取消。
示例代码:
import { onBeforeRouteLeave, onBeforeRouteUpdate } from 'vue-router'
import { ref } from 'vue'// 与 beforeRouteLeave 相同,无法访问 `this`
onBeforeRouteLeave((to, from) => {const answer = window.confirm('确定要离开当前页面? 你并未保存更改信息哦!')// 取消导航并停留在同一页面上if (!answer) return false
})const userData = ref()// 与 beforeRouteUpdate 相同,无法访问 `this`
onBeforeRouteUpdate(async (to, from) => {//仅当 id 更改时才获取用户,例如仅 query 或 hash 值已更改if (to.params.id !== from.params.id) {userData.value = await fetchUser(to.params.id)}
})
5.6 完整的导航解析流程
- 导航被触发。
- 在失活的组件里调用
onBeforeRouteLeave
守卫。 - 调用全局的
beforeEach
守卫。 - 在重用的组件里调用
onBeforeRouteUpdate
守卫(2.2+)。 - 在路由配置里调用
beforeEnter
。 - 解析异步路由组件。
- 在被激活的组件里调用
beforeRouteEnter
(选项式API)。 - 调用全局的
beforeResolve
守卫(2.5+)。 - 导航被确认。
- 调用全局的
afterEach
钩子。 - 触发 DOM 更新。
- 调用
beforeRouteEnter
(选项式API)守卫中传给next
的回调函数,创建好的组件实例会作为回调函数的参数传入。
注:在组件卸载时,所有路由守卫会被移除。
相关文章:

【Vue3 生态】VueRouter 路由核心知识点
1. 动态路由 1.1 动态路由匹配 路由分为静态路由和动态路由。上面讲过的类似 ‘/login’ 这样写死的就是静态路由。 动态路由通过在路径中使用一个动态字段(简称:路径参数),来将不同的信息映射到同一个组件中。 如:…...

SpringCloud-Nacos配置管理
文章目录 Nacos配置管理统一配置管理在nacos中添加配置文件从微服务拉取配置 配置热更新方式一方式二 配置共享1)添加一个环境共享配置2)在user-service中读取共享配置3)运行两个UserApplication,使用不同的profile3)运…...

物流智能分拣管理
电子商务的兴起,实体消费和虚拟消费结合的方式加快商品流通速度。计算机硬件和软件结合,改变了现代社会的工作和生活。线上和线下的消费方式这种消费观念新颖,受到很多年轻消费者的青睐。不同的时期有不同的经济运行机制,电子是一…...

Qt编写视频监控系统79-四种界面导航栏的设计
一、前言 最初视频监控系统按照二级菜单的设计思路,顶部标题栏一级菜单,左侧对应二级菜单,最初采用图片在上面,文字在下面的按钮方式展示,随着功能的增加,二级菜单越来越多,如果都是这个图文上…...

界面开发框架Qt新手入门教程:如何使用Calendar组件创建日历(二)
Qt 是目前最先进、最完整的跨平台C开发工具。它不仅完全实现了一次编写,所有平台无差别运行,更提供了几乎所有开发过程中需要用到的工具。如今,Qt已被运用于超过70个行业、数千家企业,支持数百万设备及应用。 本文中的CalendarWi…...

charles unknown 问题和手机代理设置(iOS手机)
一、Charles下载 下载地址:https://www.charlesproxy.com/download/ 二、Charles配置代理 1.查看本机IP:help-->Local IP Address 2.查看或者设置访问端口:Proxy->Proxy Settings 3.设置不代理计算机的请求(推荐࿰…...

【备战秋招】每日一题:2023.03.26-阿里OD机试(第三题)-数组之和最小值
为了更好的阅读体检,可以查看我的算法学习网站 在线评测链接:P1119 题目内容 塔子哥是一个热爱数学的年轻数学家,他对数字和因子分解有着深入的研究。 有一天,他在一次偶然的探索中发现了一款神奇的游戏,名为“除数游戏”。 在…...

网站的SEO优化:提升搜索引擎可见性的关键步骤
93. 网站的SEO优化:提升搜索引擎可见性的关键步骤 SEO(Search Engine Optimization)是指通过优化网站的内容、结构、链接和其他因素,以提高网站在搜索引擎结果页面(SERP)中的排名和可见性的过程。 优化网…...

Spring Boot 中的服务注册是什么,原理,如何使用
Spring Boot 中的服务注册是什么,原理,如何使用 Spring Boot 是一个非常流行的 Java 后端框架,它提供了许多便捷的功能和工具,使得开发者可以更加高效地开发微服务应用。其中,服务注册是 Spring Boot 微服务架构中非常…...

spring.factories文件在Spring工程中的说明
说明 spring.factories 是 Spring Boot 框架中一个特殊的配置文件,它用于定义自动配置的实现类以及要注册的其他组件信息。该文件通常位于 META-INF/spring.factories 目录下,Spring Boot 在启动时会自动加载它并读取其中的配置信息。 spring.factorie…...

常见的自动化测试架构有哪些?
目录 前言 常见的自动化架构包括如下。 1.数据驱动测试 2.模块驱动测试 3.关键字驱动测试 优点: 缺点: 总结: 前言 一个自动化测试架构就是一个集成体系,其中定义了一个特殊软件产品的自动化测试规则。这一体系中包含测试…...

Revit中用自适应创建简单的瓦片族和切换构件的材质?
一、Revit中使用自适应创建瓦片族 在我们的日常生活中,屋顶的瓦片是我们经常都能够见到的,瓦片能够挡风遮雨也能够使建筑物带来古香古色的气息,那我们今天来学习如何使用自适应创建简单的瓦片族。 1.首先:我们打开自适应公制常规模…...

Spring Boot实战:拦截器和监听器的应用指南
当使用Spring Boot时,我们可以通过拦截器(Interceptor)和监听器(Listener)来实现对请求和响应的处理。拦截器和监听器提供了一种可插拔的机制,用于在请求处理过程中进行自定义操作,例如记录日志…...

为什么要搭建数据仓库
数据是企业中最重要的资源之一,因此,随着企业数据量的不断增大和复杂度的提高,建立一个可靠和健全的数据仓库变得越来越重要。在数聚股份看来,一个数据仓库可以作为一个企业数据存储和管理系统,能够更有效地存储、管理…...

Sql Server 获取连续日期时间
获取连续日期时间 在项目中,有时候需要按日期/时间统计,例如2023-06-21至2023-06-28期间每一天的数据,如果某一天没有数据,也要查询出来,用NULL处理。 1.示例 2.连续日期效果SQL DECLARE StartDate DATE 2023-06-2…...

MIT 6.830数据库系统 -- lab two
MIT 6.830数据库系统 -- lab two 项目拉取Lab Two实现提示练习一 -- Filter and Join练习二 -- Aggregates练习三 -- HeapFile Mutability练习四 -- Insertion & deletion练习五 -- Page eviction练习六 -- Query walkthrough练习七 - 查询解析 项目拉取 原项目使用ant进行…...

React基础知识点(一)
React基础知识点 目标 能够说出React是什么能够说出React的特点能够掌握React的基本使用能够使用React脚手架 什么是React (★★★) React是一个用于构建用户界面的javaScript库,起源于facebook的内部项目,后续在13年开源了出…...

机器学习-进化算法
进化算法 遗传算法(Genetic Algorithm,GA)crossovermutation 进化策略(Evolutionary Strategies,ES)基因编程(Genetic Programming)Multi-objective Evolutionary Algorithms 遗传算…...

leetcode 637. 二叉树的层平均值
2023.6.29 依旧是层序遍历的变体,在层序遍历的代码中的内层循环求个和,然后出循环之后取个平均值即可实现层平均值,下面上代码: class Solution { public:vector<double> averageOfLevels(TreeNode* root) {vector<doub…...

7-数组创建函数还有哪些?【视频版】
目录 问题视频解答 问题 视频解答 点击观看: 7-数组创建函数还有哪些?...

webrtc源码阅读之P2P流程分析
P2P从宏观原理上其实就是: 收集本地Candidates设置远程Candidates连通性测试及排序 本文我们从Offer端的角度进行源码分析,学习webrtc是如何进行P2P连接的。版本m98。 一、收集本地Candidates examples/peerconnection中,CreateOffer以后&…...

vscode 快速修复(quick fix) 快捷键(Ctrl + .)被占用问题解决方法
vscode 快速修复(quick fix) 快捷键(Ctrl .)被占用 微软拼音的中/英文标点切换的快捷键为Ctrl .,与 vscode 快速修复(quick fix)快捷键冲突。修复方法如下: 切换到微软拼音,在输入法中或英字上,点击右键。 再点设置 - 按键。 …...

阿里云——扩展Linux系统盘
扩展分区和文件系统_Linux系统盘 {#concept_ocb_htw_dhb .concept} 本文提供了如何使用growpart和resize2fs工具完成Linux系统盘分区扩容及文件系统扩展的操作指导。 适用范围 {#section_u9c_3g5_ljs .section} 本文的操作步骤适用于以下分区和文件系统格式的云盘࿱…...

TypeScript ~ 掌握基本类型 ②
作者 : SYFStrive 博客首页 : HomePage 📜: TypeScript ~ TS 📌:个人社区(欢迎大佬们加入) 👉:社区链接🔗 📌:觉得文章不错可以点点关注 &…...

【Zookeeper】win安装随笔
目录 下载地址下载目标解压后目录结构配置文件配置文件详情伪分布式安装LinuxZooKeeper audit is disabled启动解决报错:SLF4J: Class path contains multiple SLF4J bindings. _ 下载地址 https://zookeeper.apache.org/releases.html 下载目标 记住选择带bin的…...

Unity 之 最新原生广告Ads接入 -- 助力增长游戏收益
Unity 之 最新Ads原生广告接入流程详解和工具类分享 一,注册 Unity Ads 广告 SDK二,下载 Unity Ads 广告 SDK三,配置 Unity Ads 广告 SDK3.1 广告位展示流程3.2 代码初始化 四,集成 Unity Ads 广告 SDK4.1 相关介绍4.2 代码分享 五…...

ChatGPT是否可以进行逻辑推理?
ChatGPT在逻辑推理方面的能力存在一定的限制。虽然它可以处理一些简单的逻辑问题,但由于其基于统计模型和语言模式的生成方式,它在复杂的逻辑推理和推断任务上可能会遇到挑战。以下是对ChatGPT在逻辑推理方面能力的详细分析: 1. 基于统计模型…...

TP6在composer包里写控制器
前提:首先要了解下如何自建composer包。 1.先建一个空包,加一个文件:composer.json {"name": "test/ctrs","type": "library","license": "MIT","autoload": {&quo…...

Java面试Day11
1. MySQL 事务有哪些隔离级别、分别有什么特点,以及 MySQL 的默认隔离级别是什么? 在MySQL中事务的隔离级别是为了解决常见的并发问题,在保证数据库性能的同时保持事务的隔离性,常见的并发问题有: 脏读:如果…...

python生成日报
目录 一:日报生成工具二:日报工具使用方式三:最终日报生成展示 一:日报生成工具 #!/usr/bin/python # coding:utf8class GetHtml(object):def __init__(self):self._html_head """<html><body style&qu…...