vue-router 命名视图(Named Views)完全指南:同一路由渲染多个组件的布局方案

发布时间:2026/9/21 1:37:41
vue-router 命名视图(Named Views)完全指南:同一路由渲染多个组件的布局方案 vue-router 命名视图Named Views完全指南同一路由渲染多个组件的布局方案【免费下载链接】vue-router The official router for Vue 2项目地址: https://gitcode.com/gh_mirrors/vu/vue-router导读在 Vue 2 单页应用中vue-router默认只提供一个视图出口router-view一条路由对应渲染一个组件。但在真实项目中我们常常需要同屏多视图的布局——例如一个同时包含主内容区main与侧边栏sidebar的页面。命名视图Named Views正是为此设计的它允许在一条路由下同时渲染多个组件到多个具名出口中。本文基于本仓库官方文档与源码系统讲解命名视图的定义方式、底层实现原理、嵌套命名视图的进阶布局以及如何用仓库内示例与端到端测试验证效果。什么是命名视图从嵌套到平铺的布局思路什么时候需要命名视图常规做法是把视图一层层嵌套父路由渲染父组件父组件内部再放一个router-view渲染子路由组件可参考仓库文档 嵌套路由。但有些布局无法用嵌套表达——例如一个页面同时显示主内容 侧边栏 底部栏这几个区域是平级的而不是父子包含关系。此时就轮到命名视图登场。正如仓库官方文档docs-gitbook/de/essentials/named-views.md所述与其只有一个视图出口不如提供多个并分别给它们命名。未命名的router-view会被自动赋予默认名default。基本写法三个具名出口在模板中放置多个router-view用name属性区分router-view classview one/router-view router-view classview two namea/router-view router-view classview three nameb/router-view第一个没有name属性等价于namedefault第二、三个分别名为a、b。路由配置必须使用components复数视图由组件渲染多个视图自然需要多个组件。因此同一条路由下配置多个组件时必须使用components带 s 的复数形式选项而不是componentconst router new VueRouter({ routes: [ { path: /, components: { default: Foo, a: Bar, b: Baz } } ] })components是一个对象键对应router-view的name值是对应的组件。上例中default出口渲染Foo、a出口渲染Bar、b出口渲染Baz。底层原理RouterView 如何按名称取组件name属性的默认值命名视图的核心实现位于 src/components/view.js。它是一个函数式组件functional其props定义如下src/components/view.jsexport default { name: RouterView, functional: true, props: { name: { type: String, default: default } }, ... }从这里可以确认不带name的router-view的默认名称就是字符串default与官方文档描述完全一致。匹配过程depth 与 matched.components[name]RouterView的渲染逻辑src/components/view.js按以下步骤工作计算视图深度depth遍历父级链统计出现了多少个带routerView标记的祖先节点从而知道当前出口处于路由记录的哪一层用于配合嵌套路由。按深度取出匹配的路由记录const matched route.matched[depth]即当前路由在该深度上匹配到的记录。按名称取组件const component matched matched.components[name]——这正是命名视图的命根子组件来源于路由记录RouteRecord上的components字典用当前出口的名称作为键去取。取不到就渲染空节点如果当前没有匹配记录或该记录上没有对应名称的组件!matched || !component则渲染一个空节点h()对应的出口位置什么都不显示。路由记录如何归一化 components无论你写的是单数component还是复数components最终都会在构建路由表时被归一化为字典。源码 src/create-route-map.js 中的addRouteRecord是这样处理的const record: RouteRecord { path: normalizedPath, regex: compileRouteRegex(normalizedPath, pathToRegexpOptions), components: route.components || { default: route.component }, ... props: route.props null ? {} : route.components ? route.props : { default: route.props } }关键结论只写component: Foo时等价于components: { default: Foo }——所以单视图本质是默认名视图的特例当使用components复数形式时props也应改为字典形式按视图名称分别传 props源码对此做了显式区分详见下文命名视图与 props一节。类型定义也能佐证这一点types/router.d.ts 中定义了RouteConfigSingleView含component与RouteConfigMultipleViews含components?: DictionaryComponent两者共同组成RouteConfig联合类型。仓库内的完整可运行示例官方文档提到的工作 Demo 对应的就是仓库中的 examples/named-views/app.js页面骨架见 examples/named-views/index.html。它比文档示例更进一步演示了同一条路由配置的两套具名组件映射import Vue from vue import VueRouter from vue-router Vue.use(VueRouter) const Foo { template: divfoo/div } const Bar { template: divbar/div } const Baz { template: divbaz/div } const router new VueRouter({ mode: history, base: __dirname, routes: [ { path: /, // a single route can define multiple named components // which will be rendered into router-views with corresponding names. components: { default: Foo, a: Bar, b: Baz } }, { path: /other, components: { default: Baz, a: Bar, b: Foo } } ] }) new Vue({ router, template: div idapp h1Named Views/h1 ul lirouter-link to///router-link/li lirouter-link to/other/other/router-link/li /ul router-view classview one/router-view router-view classview two namea/router-view router-view classview three nameb/router-view /div }).$mount(#app)可以这样运行验证仓库只读仅介绍运行方式yarn install yarn run dev # 浏览器访问 http://localhost:8080/named-views/导航到/other时同一组三个出口会切换到另一套组件映射default变Baz、b变Foo直观体现了一条路由 ↔ 多组件的能力。端到端测试中的行为断言仓库的端到端测试 test/e2e/specs/named-views.js 对上述行为做了完整断言可作为行为规范参考访问/named-views/时.view.one文本为foo、.view.two为bar、.view.three为baz点击链接跳转到/named-views/other后.view.one变为baz、.view.two仍为bar、.view.three变为foo直接刷新访问/named-views/other模拟首次进入断言结果同样成立。这证明命名视图的组件解析与 URL 完全联动且能正确处理直接访问 应用内跳转两种场景。进阶嵌套命名视图构建复杂布局命名视图可以与嵌套路由组合构建类似设置中心的多面板布局。英文版官方文档docs/guide/essentials/named-views.md给出了一个经典的 Settings 示例外层是UserSettings页面内部同时存在普通导航组件Nav、默认出口以及一个名为helper的具名出口不同子路由/settings/emails与/settings/profile在默认出口渲染不同内容同时helper出口可选择性渲染预览组件。UserSettings 组件的模板!-- UserSettings.vue -- div h1User Settings/h1 NavBar/ router-view/ router-view namehelper/ /div其中NavBar是普通组件与路由无关无name的router-view/渲染默认组件router-view namehelper/渲染名为helper的组件——如果当前路由没有配置helper该出口渲染为空节点对应上文源码中!component时return h()的行为。嵌套命名视图的路由配置{ path: /settings, // You could also have named views at the top component: UserSettings, children: [{ path: emails, component: UserEmailsSubscriptions }, { path: profile, components: { default: UserProfile, helper: UserProfilePreview } }] }要点顶层/settings用单数component: UserSettings渲染外层壳子路由emails使用单数component此时helper出口为空子路由profile使用复数components同时填充默认出口与helper出口。结合 src/components/view.js 的深度计算逻辑可知子路由中的router-view会因父级UserSettings中存在 routerView 标记而使depth递增从而正确匹配route.matched[depth]这一层记录——这正是嵌套命名视图在源码层面的支撑机制。命名视图与 props字典形式的传参使用命名视图时如果还需要向各视图组件传 propsprops同样要用字典形式每个名称一个配置与components一一对应。这一点由类型定义明确约束types/router.d.tsinterface RouteConfigMultipleViews extends _RouteConfigBase { components?: DictionaryComponent props?: Dictionaryboolean | Object | RoutePropsFunction }底层解析位于 src/components/view.js渲染时会取matched.props matched.props[name]即当前视图名称对应的 props 配置随后通过fillPropsinData将解析出的 props 传给组件未被组件声明为 props 的字段会被降级为普通 attrs。resolveProps支持三种形态src/components/view.jsobject直接作为 props 传入function接收route参数、返回 props 对象常用于动态传参booleantrue时把route.params作为 props 传入。常见误区与注意事项单复数混淆多视图必须用components用了单数component则只有默认出口生效。源码route.components || { default: route.component }也解释了为何混用容易困惑——单数写法会被归一化为default键。默认名记忆不带name的出口叫default配置时写default: Foo即可覆盖它不必额外加namedefault。未配置即空白某条路由若没给某个具名出口提供组件该出口渲染为空节点不会报错源码 src/components/view.js。这在同一布局、部分区域按路由条件显示的场景中非常实用。嵌套时注意层级子路由中要使用命名视图需确保父组件模板里已放置对应名称的router-view且通过父链上的routerView标记让深度计算正确源码 src/components/view.js。命名路由与默认子路由的坑源码 src/create-route-map.js 会警告带name且含有默认子路由path: 的父路由使用:to{ name: ... }导航时默认子路由不会渲染应改用子路由自己的名字。小结命名视图是 vue-router 构建同屏多区布局的标准方案模板侧用多个具名router-view声明出口路由配置侧用components字典键为出口名映射组件源码侧由RouterView按名称从route.matched[depth].components取值渲染。本文结合 src/components/view.js、src/create-route-map.js、examples/named-views/app.js 与 test/e2e/specs/named-views.js 展示了从能用到懂原理的完整链路。更多相关概念可继续阅读仓库文档中的 嵌套路由 与 命名路由。【免费下载链接】vue-router The official router for Vue 2项目地址: https://gitcode.com/gh_mirrors/vu/vue-router创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询