前言
上节我们学习了命名路由name的含义,并且分析了源码如何从name定位到具体的页面,本节我们来学习一下与命名路由相似的命名视图。
命名视图
第一节我们学习了router-view组件,页面中必须要使用router-view组件才会显示出来,一般页面会写一个router-view,如果我们在页面中写两个router-view会发生什么呢?
js
<template>
<router-view></router-view>
<router-view></router-view>
</template>

很明显,router-view对应的组件都渲染出来了,所以一个页面可以拥有多个router-view,相当于多个组件同级展示,如果我们想要不同内容的router-view渲染出来,就需要使用name属性为该视图赋个名字,这就是命名视图。我们写个简单的例子,在一个路由展示左右两个视图,左视图用Left、右视图用Right:
js
<template>
<router-view name="Left"></router-view>
<router-view name='Right'></router-view>
</template>
打开路由发现页面是空白的,我们知道视图对应着组件,当我们将视图命名后那么就需要对应一个全新的组件,接下来我们就要创建命名视图对应的组件。同时路由跟视图也对应着,当我们使用多个视图时,必须在components添加对应的组件。
js
components: {
default: Table,
Left,
Right
}

注意:
- router-view的name属性默认是default,default的组件就是router-view对应的;
- Left、Right是简写模式,当视图的name属性与组件名称相同时可以简写为一个。
源码
知道了命名视图的定义与用法,我们来解析下源码。打开vue-router源码,在src文件夹中找到RouterView.ts文件。

源码中首先import了用到的方法、类型,其中从vue引入的最多,我们需要了解关键的几个API:
- defineComponent:定义vue组件的辅助函数。
- h:创建虚拟dom的节点。
接着运用了defineComponent定义了组件RouterViewImpl,该组件包括name与route两个proprs参数,name的默认值就是default。

在定义的组件中使用了组合式API------setup,寻找用name参数的地方,就在return函数中:

这个函数就是命名视图渲染的核心逻辑:
- 根据name参数获取了currentName ,拿着currentName获取了ViewComponent 。很明显ViewComponent就是name对应的组件,该组件在路由配置项components中,一切跟上面的用法一致。注意ViewComponent取值用了!符号,这里是断言的意思 ,表示该值一定不为空。
2.获取组件props参数,利用h函数创建虚拟dom得到component。在创建之前,专门声明了onVnodeUnmounted函数去卸载实例,防止内存泄漏。
3.返回插槽写法与component,以此来兼容动态组件。最终RouterView就是等于RouterViewImpl包括props参数与slot插槽。 这就是name命名视图渲染的一个过程,通过name找到对应的compoent,然后渲染出来,逻辑是非常简单的。
总结
以上就是命名视图的过程,本节我们感受到router、component之间的联系,vue-router本质亦是如此。