vue3项目怎么写路由 + 浅析vue-router4源码

news2024/11/23 3:00:53

在SPA项目里,路由router基本是前端侧处理的,那么vue3项目中一般会怎么去写router呢,本文就来讲讲vue-router4的一些常用写法,以及和Composition API的结合使用,同时简单讲讲实现原理,让你轻松理解前端router的原理。

基础配置

安装命令

入口引入

第一步是在main.ts的入口文件里引入router的插件

这里讲解下history这个配置

createWebHashHistory:指的是用hash模式路由,比如/#/order/detail这种带#的path

其他配置还有:

createWebHistory:基于html5原生的history API实现路由

createMemoryHistory:基于内存信息来隐式管理路由,适用于SSR场景

除了上面main.ts入口的配置,还需要在你的App.vue入口组件里使用<router-view>,这样路由匹配的视图就会加载在这个组件下面。

路由配置

入口配置完了,接下来就是各个分路由怎么配置

上面的代码就是之前提到的router文件,path是页面的路径,compnent对应视图组件

一般来说还会存在动态params的情况

这里的id其实就是一个动态参数,/order/123/order/80EA都能匹配上,id的格式也没做限定

如果想要id只匹配数字可以看以下写法,括号内是正则表达式,注意\会有转义问题,需要写成\\

如果在路径上可以做一些复用,也可以参考以下写法:

这里的路径就是/order/list/order/detail,不过要注意第二个path带头不能带/,不然会被当做从根path匹配。

在构造比较复杂的应用时,推荐使用动态import的方式引入组件,缩短各个页面首次加载的时间,并优化用户体验,代码如下:

打包的产物会进行分包,会在路由匹配的时候才会加载进来

路由守卫 - 维护登录态

有这么一个场景,后台系统设置了10天登录态失效的机制,那么10天后前端页面该怎么操作提示呢,这里的最佳实践就是结合vue-router的路由守卫

路由守卫听名字很拗口,但是看api你其实就明白是怎么回事了,router.beforeEach,beforeEach其实就是每次在匹配路由配置的时候,在生效之前会执行的一个函数

这个代码就是一个简单的判断登录态并适配是否跳转登录页面的逻辑

Composition API

上面主要是整体系统层面的一些配置和逻辑,接下来讲讲各个独立组件里如何配合vue-router来获取路由信息,这里主要介绍Composition API的风格写法。

useRoute

setup中可以直接引用useRoute来获取route实例,然后id就是上面配置过的动态信息

为方便使用,下面把route下的常用字段介绍下

字段名含义例子
fullPath全路径/order/8223?query1=123#hash1
hash二次包装的哈希值#hash1
matched匹配的route配置列表Array
nameroute中的name配置
paramspath的参数解析对象{id: “8223”}
path路径/order/8223
queryquery的解析对象{query1: “123”}

这里还有个细节,就是useRoute可以在这个组件下个任何层级使用,不需要pinia这类工具进行公共状态管理,在实际用起来还是挺方便的

这里来看下源码其实就很容易发现原理,就是用了依赖注入的方式进行路由的状态共享

细节:routeLocationKey是使用Symbol作为注入名,为了防止不同库使用依赖注入导致命名冲突

这里是插件应用层的provider注册

currentRoute可以理解为对当前路由的动态映射,路由变化后会更新

useRouter

有了上面的hooks经验,那这个useRouter就很好理解了,会返回一个Router实例,Router实例能够帮助在js中实现路由的跳转:

上面的代码可以实现从当前页面跳转到搜索页面,并带上当前页面所有的query参数

如果是不需要返回的强制跳转可以使用router.replace

route-view简易原理

这里再来讲讲vue-router核心的组件route-view,这个其实是实现spa单页应用路由替换的核心组件,下面的代码是我把源码精简后的伪代码,注释处都是比较核心的处理逻辑。

主要功能:

  • 根据不同路由信息匹配组件
  • 监听路由变化并执行beforeEach这类回调
  • 对全局的依赖注入进行更新
defineComponent({
	setup(props, { attrs, slots }) {// 类似于useRouteconst injectedRoute = inject(routerViewLocationKey)!const routeToDisplay = computed(() => props.route || injectedRoute.value)const injectedDepth = inject(viewDepthKey, 0)// 这里获取route列表匹配的第一个const depth = computed<number>(() => {let initialDepth = unref(injectedDepth)const { matched } = routeToDisplay.valuelet matchedRoutewhile ((matchedRoute = matched[initialDepth]) &&!matchedRoute.components) {initialDepth++}return initialDepth})const matchedRouteRef = computed(() => routeToDisplay.value.matched[depth.value])// 对全局提供各个参数provide(viewDepthKey,computed(() => depth.value + 1))provide(matchedRouteKey, matchedRouteRef)provide(routerViewLocationKey, routeToDisplay)// 这里是监听路由变化并调用回调,beforeEach就是这里执行的watch(() => [matchedRouteRef.value, props.name] as const,([instance, to, name], [oldInstance, from, oldName]) => {(to.enterCallbacks[name] || []).forEach(callback =>callback(instance))},{ flush: 'post' })return () => {const route = routeToDisplay.valueconst currentName = props.nameconst matchedRoute = matchedRouteRef.value// 这里找到匹配的componentconst ViewComponent =matchedRoute && matchedRoute.components![currentName]const routePropsOption = matchedRoute.props[currentName]const routeProps = routePropsOption? routePropsOption === true? route.params: typeof routePropsOption === 'function'? routePropsOption(route): routePropsOption: nullconst component = h(ViewComponent,assign({}, routeProps, attrs))return (component)}}
}) 

最后

为大家准备了一个前端资料包。包含54本,2.57G的前端相关电子书,《前端面试宝典(附答案和解析)》,难点、重点知识视频教程(全套)。



有需要的小伙伴,可以点击下方卡片领取,无偿分享

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

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

相关文章

【04】FreeRTOS的任务挂起与恢复

目录 1.任务的挂起与恢复的API函数 1.1任务挂起函数介绍 1.2任务恢复函数介绍&#xff08;任务中恢复&#xff09; 1.3任务恢复函数介绍&#xff08;中断中恢复&#xff09; 2.任务挂起与恢复实验 3.任务挂起和恢复API函数“内部实现”解析 3.1vTaskSuspend() 3.2&#…

Prometheus基础

一、何为Prometheus Prometheus受启发于Google的Brogmon监控系统&#xff08;相似的Kubernetes是从Google的Brog系统演变而来&#xff09;&#xff0c;从2012年开始由前Google工程师在Soundcloud以开源软件的形式进行研发&#xff0c;并且于2015年早期对外发布早期版本。2016年…

【基础】Netty 的基础概念及使用

Netty基本概念理解阻塞与非阻塞同步与异步BIO 与 NIOReactor 模型Netty 基本概念Netty 的执行流程Netty 的模块组件Netty 工作原理Netty 的基本使用Netty ServerNetty Client参考文章基本概念理解 阻塞与非阻塞 阻塞与非阻塞是进程访问数据时的处理方式&#xff0c;根据数据是…

系分 - 案例分析 - 系统维护与设计模式

个人总结&#xff0c;仅供参考&#xff0c;欢迎加好友一起讨论 文章目录系分 - 案例分析 - 系统维护与设计模式典型例题 1题目描述参考答案典型例题 2题目描述参考答案系分 - 案例分析 - 系统维护与设计模式 典型例题 1 题目描述 某企业两年前自主研发的消防集中控制软件系统…

05-requests添加Cookies与正则表达式

第5讲 requests添加Cookies与正则表达式 整体课程知识点查看 &#xff1a;https://blog.csdn.net/j1451284189/article/details/128713764 本讲总结 request代理使用 request SSL request添加Cookies 数据解析方法简介 数据解析&#xff1a;正则表达式讲解 一、requests 代理 …

【23种设计模式】学习汇总(未完结+思维导图)

获取思维导图翻至底部底部&#xff0c;基本概览博客内容&#xff08;暂未完全完善&#xff0c;期待你的持续关注&#xff09; 写作不易&#xff0c;如果您觉得写的不错&#xff0c;欢迎给博主来一波点赞、收藏~让博主更有动力吧&#xff01; 一.相关内容 在软件工程中&#xf…

关系型数据库RDBMS | 字节青训营笔记

一、经典案例 1、红包雨案例 每年春节&#xff0c;抖音都会有红包雨获得 2、事务 事务(Transaction): 是由一组SQL语句组成的一个程序执行单元(Unit)&#xff0c;它需要满足ACID特性 BEGIN; UPDATE account table SET balance balance - 小目标 WHERE name “抖音; UPDATE…

指数加权平均、动量梯度下降法

目录1.指数加权平均(exponentially weighted averages)这里有一年的温度数据。如果想计算温度的趋势&#xff0c;也就是局部平均值(local average)&#xff0c;或者说移动平均值(moving average)&#xff0c;怎么做&#xff1f;&#xff1a;当天的温度&#xff0c;&#xff1a;…

交换机的基本原理(特别是动态ARP、静态ARP、代理ARP)

第六章&#xff1a;交换机的基本配置 二层交换设备工作在OSI模型的第二层&#xff0c;即数据链路层&#xff0c;它对数据包的转发是建立在MAC&#xff08;Media Access Control &#xff09;地址基础之上的。二层交换设备不同的接口发送和接收数据独立&#xff0c;各接口属于不…

esxi宿主机进入维护模式虚拟机不会自动释放【不会自动迁移出去】解决方法、查看辨别宿主机本地空间和存储池、esxi进入存储内部清理空间

文章目录说明虚拟机不自动释放处理过程报错说明宿主机进入维护模式说明手动迁移报错说明直接启动虚拟机报错说明解决方法报错原因分析解决方法查看辨别宿主机本地空间esxi进入存储内部清理空间进入存储池内存储内部空间清理及原则存储空间说明说明 我当前的esxi主机版本为5.5 …

7亿人养活的眼镜行业,容不下一家县城小店

文|螳螂观察 作者| 青月 如果要盘点那些被暴利眷顾的行业&#xff0c;眼镜零售肯定榜上有名。 从上市企业的财报数据来看&#xff0c;国内眼镜零售行业的首家上市公司——博士眼镜&#xff0c;2021年前三季度的平均毛利率超过60%&#xff1b;国内镜片第一股明月眼镜在2021年…

【C进阶】文件操作

⭐博客主页&#xff1a;️CS semi主页 ⭐欢迎关注&#xff1a;点赞收藏留言 ⭐系列专栏&#xff1a;C语言进阶 ⭐代码仓库&#xff1a;C Advanced 家人们更新不易&#xff0c;你们的点赞和关注对我而言十分重要&#xff0c;友友们麻烦多多点赞&#xff0b;关注&#xff0c;你们…

小程序应用生命周期

小程序应用生命周期生命周期介绍应用生命周期钩子函数参数对象页面生命周期页面生命周期-页面参数组件生命周期生命周期介绍 定义 一个组件或者页面生老病死的过程一堆会在特定时期触发的函数 分类 应用生命周期页面生命周期组件生命周期 应用生命周期钩子函数 属性说明onL…

Xpath Helper 在新版Edge中的安装及解决快捷键冲突问题

&#x1f935;‍♂️ 个人主页老虎也淘气 个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f44d;&#x1f3fb; 收藏…

vue2源码分析-keep-alive组件

简介 keep-alive是Vue.js的一个内置组件。它能够将指定的组件实例保存在内存中&#xff0c;而不是直接将其销毁&#xff0c;它是一个抽象组件&#xff0c;不会被渲染到真实DOM中&#xff0c;也不会出现在父组件链中。 具体用法咱们这里就不再细说了&#xff0c;今天主要是探讨…

JavaEE day2 初识web与HTML

初步了解相关知识 关于端口&#xff08;port&#xff09;&#xff1a;一个端口同一时间只能被一个进程监听&#xff0c;但是一个进程可以监听多个端口 URL的标准格式&#xff1a;协议名称&#xff1a;//主机/资源路径&#xff1f;查询字符串#文档片段 一般协议最常见的为htt…

Java基础之《netty(25)—handler链调用机制》

一、netty的handler的调用机制 1、使用自定义的编码器和解码器来说明netty的handler调用机制。 客户端发送long -> 服务器 服务端发送long -> 客户端 2、案例 二、客户端发送给服务端 1、服务端 NettyServer.java package netty.inboundhandlerAndOutboundhandler;i…

【C++】从0到1入门C++编程学习笔记 - 基础入门篇:程序流程结构

文章目录一、选择结构1.1 if 语句1.2 三目运算符1.3 switch语句二、循环结构2.1 while 循环语句2.2 do...while 循环语句2.3 for 循环语句2.4 嵌套循环三、跳转语句3.1 break 语句3.2 continue 语句3.3 goto 语句C/C支持最基本的三种程序运行结构&#xff1a;顺序结构、选择结构…

MySQL进阶——优化

1、选择最合适的字段属性 Mysql是一种关系型数据库&#xff0c;可以很好地支持大数据量的存储&#xff0c;但是一般来说&#xff0c;数据库中的表越小&#xff0c;在它上面执行的查询也就越快。因此&#xff0c;在创建表的时候&#xff0c;为了获得更好的性能&#xff0c;我们…

腾讯云HiFlow场景连接器 联动对象存储企业网盘,打通数据分发“最后一公里”

对云厂商和企业用户来说&#xff0c;随着数据规模的快速增长&#xff0c;企业除了对存储功能和性能的要求不断增加&#xff0c;也越来越注重数据分发的效率。在传统数据分发的过程中&#xff0c;数据管理员往往需要先在存储桶下载对应的客户方案/交付资料&#xff0c;再使用微信…