vue-router 源码分析——7.命名视图

这是对vue-router 3 版本的源码分析。
本次分析会按以下方法进行:

  1. 按官网的使用文档顺序,围绕着某一功能点进行分析。这样不仅能学习优秀的项目源码,更能加深对项目的某个功能是如何实现的理解。这个对自己的技能提升,甚至面试时的回答都非常有帮助。
  2. 在围绕某个功能展开讲解时,所有不相干的内容都会暂时去掉,等后续涉及到对应的功能时再加上。这样最大的好处就是能循序渐进地学习,同时也不会被不相干的内容影响。省略的内容都会在代码中以…表示。
  3. 每段代码的开头都会说明它所在的文件目录,方便定位和查阅。如果一个函数内容有多个函数引用,这些都会放在同一个代码块中进行分析,不同路径的内容会在其头部加上所在的文件目录。

本章讲解router中命名路由是如何实现的。
另外我的vuex3源码分析也发布完了,欢迎大家学习:
vuex3 最全面最透彻的源码分析
还有vue-router的源码分析:
vue-router 源码分析——1. 路由匹配
vue-router 源码分析——2. router-link 组件是如何实现导航的
vue-router 源码分析——3. 动态路由匹配
vue-router 源码分析——4.嵌套路由
vue-router 源码分析——5.编程式导航
vue-router 源码分析——6.命名路由

官方定义

  • 有时候想同时 (同级) 展示多个视图,而不是嵌套展示,例如创建一个布局,有 sidebar (侧导航) 和 main (主内容) 两个视图,这个时候命名视图就派上用场了。你可以在界面中拥有多个单独命名的视图,而不是只有一个单独的出口。如果 router-view 没有设置名字,那么默认为 default。特意强调确保正确使用 components 配置 (带上 s)
<router-view class="view one"></router-view>
<router-view class="view two" name="a"></router-view>
<router-view class="view three" name="b"></router-view>const router = new VueRouter({routes: [{path: '/',components: {default: Foo,a: Bar,b: Baz}}]
})
  • 注意上面使用了命名路由时,routes中使用了components做key,而不是component。同时结构变成了一个对象,存储的内容就是上面代码中的components对象。

命名视图初始化

  • 这里对应了router在初始化并创建匹配器时,对record的component的不同处理:
// create-route-map.jsfunction addRouteRecord(pathList: Array<string>,pathMap: Dictionary<RouteRecord>,nameMap: Dictionary<RouteRecord>,route: RouteConfig,parent?: RouteRecord,matchAs?: string
) {const { path, name } = route...const record: RouteRecord = {components: route.components || {default: route.component},...}...
}
  • 然后,在使用router-view组件时,传入了一个name。如果对vue开发非常熟练的,大概已经知道router是如果定位到需要的component了:
    • 在view.js组件中,用props接受父组件传入的name,同时给他一个默认值default
    • 在匹配到对应路由的record后,对应的component即为recoed.components[name]
    • 这样就实现了基本的命名视图路由匹配逻辑。
    • 同时没有匹配的record或者component,则渲染一个空节点,这个也适合后面的嵌套路由逻辑。
// ./components/view.js
...
export default {...props: {name: {type: String,default: 'default'        }    },render(...) {const name = props.nameconst matched = route.matched[depth]const component = matched && matched.components[name]if (!matched || !component) {return h()        }     ...return h(conponent, ...)     }
}

嵌套命名视图

官网例子:
/settings/emails                                       /settings/profile
+-----------------------------------+                  +------------------------------+
| UserSettings                      |                  | UserSettings                 |
| +-----+-------------------------+ |                  | +-----+--------------------+ |
| | Nav | UserEmailsSubscriptions | |  +------------>  | | Nav | UserProfile        | |
| |     +-------------------------+ |                  | |     +--------------------+ |
| |     |                         | |                  | |     | UserProfilePreview | |
| +-----+-------------------------+ |                  | +-----+--------------------+ |
+-----------------------------------+                  +------------------------------+
<!-- UserSettings.vue -->
<div><h1>User Settings</h1><NavBar/><router-view/><router-view name="helper"/>
</div>
// 路由配置
{path: '/settings',// 你也可以在顶级路由就配置命名视图component: UserSettings,children: [{path: 'emails',component: UserEmailsSubscriptions}, {path: 'profile',components: {default: UserProfile,helper: UserProfilePreview}}]
}
  • 命名视图的路由匹配规则并没有改变,这里只是多个一个children属性,同时children中的每个元素的内容又符合路由配置内容,即可以看做一个单独的route。所以在router初始化并记录路由的record时,对children进行了递归处理:
// create-route-map.jsfunction addRouteRecord(pathList: Array<string>,pathMap: Dictionary<RouteRecord>,nameMap: Dictionary<RouteRecord>,route: RouteConfig,parent?: RouteRecord,matchAs?: string
) {const { path, name } = route...const record: RouteRecord = {components: route.components || {default: route.component},parent, // 记录父record...}if (route.children) {route.children.forEach(child => {// 递归调用addRouteRecord函数,父record会赋值到child的record.parent上addRouteRecord(pathList, pathMap, nameMap, child, record)        })    }...
}
  • 回到开头的官网例子,如果我们访问的是/settings/emails,在匹配到对应的路由后,由于无法取得components[helper],所以 router-view name=“helper” 会被vue渲染成一个空节点。
<!-- UserSettings.vue -->
<div><h1>User Settings</h1><NavBar/><router-view/><router-view name="helper"/>
</div>// 路由配置
{path: '/settings',// 你也可以在顶级路由就配置命名视图component: UserSettings,children: [{path: 'emails',component: UserEmailsSubscriptions}, {path: 'profile',components: {default: UserProfile,helper: UserProfilePreview}}]
}// ./components/view.jsexport default {...props: {name: {type: String,default: 'default'        }    },render(...) {...const matched = route.matched[depth]const component = matched && matched.components[name]// 这里取不到 matched.components["helper"]if (!matched || !component) {...return h()        }}
}

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

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

相关文章

若依前后端分离 前端路由登录页 如何进行跳转

路由守卫&#xff0c;看这篇文章 http://t.csdnimg.cn/HkypThttp://t.csdnimg.cn/HkypT

MySQL存储与优化 一、MySQL架构原理

1.MySQL体系架构 MySQL Server架构自顶向下大致可以分网络连接层、服务层、存储引擎层和系统文件层 (1)网络连接层 客户端连接器&#xff08;Client Connectors&#xff09;&#xff1a;提供与MySQL服务器建立的支持。目前几乎支持所有主流的服务端编程技术&#xff0c;例如常…

有趣的递归(Recursion),一些直观的示例

从前有座山, 山上有座庙, 庙里有个老和尚在给小和尚讲故事: “从前有座山, 山上有座庙, 庙里有个老和尚在给小和尚讲故事: …” 反复而纠结的定义 看完这个故事, 对递归你已经有了印象, 很好, 这样已足够. 如果你不幸是个喜欢精确定义的人, 那么答案可能无法让你满意: 你想知…

java考试题20道

选择题 编译Java源代码文件的命令是javac javac命令是将Java源代码文件进行编译得到字节码文件(.class文件) java命令是在JVM上运行得到的字节码文件 下面是一个示例&#xff1a; javac test.java -------> test.class java test ------> 运行test.class文件下列那…

vue3 在el-input的光标处插入文本

点击文本框下方的按钮&#xff0c;将相应的文本插入光标处的实现&#xff1a; <el-input type"textarea" rows"4" v-model"formula" blur"handleBlur" clearable></el-input><el-button-group class"short_btn&q…

63、基于深度学习网络的数字分类(matlab)

1、基于深度学习网络的数字分类的原理及流程 基于深度学习网络的数字分类是一种常见的机器学习任务&#xff0c;通常使用的是卷积神经网络&#xff08;CNN&#xff09;来实现。下面是其原理及流程的简要说明&#xff1a; 数据收集&#xff1a;首先&#xff0c;需要收集包含数字…

华为高斯数据库安装

这里主要在虚拟机上安装&#xff0c;选择openEuler系统。已经有很多博文介绍了虚拟机安装&#xff0c;直接推荐博文。 OpenEulerx虚拟机中安装 openEuler添加VMware-tools 数据库的安装也有详细博文推荐 OpenGauss数据库的详细安装 借花献佛&#xff0c;大家努力

【shell script】

文章目录 一、基础shell script二、脚本运行方式的差异三、判断式1.利用test命令2.利用判断符号[] 四、if&#xff0c;case语句1.if...then2.case...esac 五、函数function六、循环1.while和until循环2.for循环 一、基础shell script 在“shell”部分&#xff0c;那是在命令行…

【Oracle】Oracle常用语句大全

目录 创建/删除数据库创建/删除表其他表操作增加字段修改字段重命名字段删除字段 主键/索引/视图相关数据插入数据更新数据删除字段拼接merge into语法案例素材同时更新和插入记录同步错误 分页查询分组查询/筛选排序连接查询1. 内连接&#xff08;INNER JOIN&#xff09;&…

Flutter——最详细(Badge)使用教程

背景 主要常用于组件叠加上圆点提示&#xff1b; 使用场景&#xff0c;消息数量提示&#xff0c;消息红点提示 属性作用backgroundColor红点背景色smallSize设置红点大小isLabelVisible是否显示offset设置红点位置alignment设置红点位置child设置底部组件 代码块 class Badge…

从数据洞察到智慧决策:数字孪生技术在智慧水利中的应用实践,为水库管理提供强有力的数据支撑和智能分析

目录 一、引言 二、数字孪生技术的核心与原理 三、数字孪生技术在智慧水利中的应用场景 1、水库管理的挑战与需求 2、数字孪生水库管理系统的构建 四、数字孪生技术在水库管理中的具体应用案例 1、洪水预测与模拟 2、水资源配置与调度 3、大坝安全监测与评估 4、生态环…

【C++/STL深度剖析】stack和queue的详细概念和使用(图文详解,初学者必看!!)

目录 一、前言 二、stack 的详细解析 &#x1f525; stack的介绍&#x1f525; &#x1f525; stack的构造&#x1f525; &#x1f525; stack的常用接口&#x1f525; &#x1f4a7;push &#x1f4a7;top &#x1f4a7;pop &#x1f4a7;empty &#x1f4a7;size…

C# Queue、List、LinkedList 性能对比

最近需要用到一个先进先出的缓存列队&#xff0c;对比了一下几个可能用的类的性能。。 向添加100w个数据&#xff0c;然后每次弹出100个&#xff0c;输出用时 Queue<int> q new Queue<int>();List<int> l new List<int>();LinkedList<int> ll…

确保跨平台自动化测试脚本的稳定运行:获取谷歌浏览器与ChromeDriver版本20240703

确保跨平台自动化测试脚本的稳定运行&#xff1a;获取谷歌浏览器与ChromeDriver版本 在自动化测试中&#xff0c;确保谷歌浏览器&#xff08;Google Chrome&#xff09;与ChromeDriver版本匹配至关重要&#xff0c;特别是跨平台&#xff08;Windows和Linux&#xff09;测试时。…

Android文件路径获取

文件存储相关的文档 文件存储相关的系列文档如下&#xff0c;可根据需要查看这些文档 Android文件路径获取 Android存储权限梳理及api接口调用 Android各种存储路径的比较 Android R及以上版本中APP外部存储实现 Android文件路径获取 在Android开发中&#xff0c;经常需要…

24位DAC转换的FPGA设计及将其封装成自定义IP核的方法

在vivado设计中,为了方便的使用Block Desgin进行设计,可以使用vivado软件把自己编写的代码封装成IP核,封装后的IP核和原来的代码具有相同的功能。本文以实现24位DA转换(含并串转换,使用的数模转换器为CL4660)为例,介绍VIVADO封装IP核的方法及调用方法,以及DAC转换的详细…

为什么除以n-1而不是n得到的样本方差是总体方差的无偏估计量

文章目录 前言具体的解释&#xff1a; 前言 在统计学中&#xff0c;我们通常使用样本方差来估计总体方差。样本方差的计算通常是将每个观测值与样本均值的差的平方和除以样本大小减去1&#xff0c;即 ( 1 n − 1 ∑ i 1 n ( x i − x ˉ ) 2 ) (\frac{1}{n-1} \sum_{i1}^{n}…

REGX52.H报错

keil cannot open source input file "REGX52.H": No such file or directory 选择下面这个目录 Keil\C51\INC\Atmel

源码扭蛋机开发初探

在软件开发的世界里&#xff0c;创新总是层出不穷。今天&#xff0c;我们将一起探讨一个有趣而富有创意的项目——源码扭蛋机。源码扭蛋机&#xff0c;顾名思义&#xff0c;就是将传统的扭蛋机概念与代码编程相结合&#xff0c;让开发者们在扭动的过程中随机获得各种有趣的、实…

【持续更新】App Inventor 2 中文网原创内容

App Inventor 2 中文网原创的技术文档&#xff0c;作品&#xff0c;技术文章&#xff0c;帖子&#xff0c;问答&#xff0c;技术指导&#xff0c;问题解决思路等。 基础知识 【连接调试】App Inventor 2 连接方式&#xff1a;AI伴侣、模拟器、USB【连接调试】Ai2 Starter模拟…