Vue3 多个router-view命名视图示例(注意components复数)

在 Vue3 中,若需要在一个页面中同时展示 ​​多个独立的路由组件​ ​(例如侧边栏、主内容区、顶部导航等),可以通过 Vue Router 提供的 ​​命名视图(Named Views)​ ​ 功能实现。命名视图允许你在布局中定义多个「路由出口」(<router-view>),每个出口对应不同的路由组件,从而实现更灵活的页面结构。

一、核心概念:命名视图(Named Views)

默认情况下,<router-view>是「默认视图」(无 name属性),只能渲染一个路由组件。而 ​​命名视图​ ​ 通过为 <router-view>添加 name属性,为每个视图分配唯一标识,允许同时渲染多个组件。

二、实现步骤:配置与使用多个 <router-view>

1. 定义页面布局(含多个 <router-view>

在需要展示多个组件的页面(通常是布局组件,如 Layout.vue)中,添加多个带 name<router-view>标签。

​示例布局(src/layouts/MainLayout.vue)​​:

xml 复制代码
<template>
  <div class="main-layout">
    <!-- 顶部导航(默认视图,name: default) -->
    <router-view></router-view>

    <!-- 主内容区(命名视图:main) -->
    <router-view name="main"></router-view>

    <!-- 侧边栏(命名视图:sidebar) -->
    <router-view name="sidebar"></router-view>
  </div>
</template>

2. 配置路由规则(关联命名视图)

在路由配置文件(如 router/index.js)中,通过 components(复数)属性为每个命名视图指定对应的组件。

​注意​ ​:components是一个对象,键为视图名称(与 <router-view name>一致),值为对应的组件。

​示例路由配置​​:

javascript 复制代码
// src/router/index.js
import { createRouter, createWebHistory } from 'vue-router'

// 导入需要的组件
import Layout from '../layouts/MainLayout.vue'  // 布局组件(包含多个 router-view)
import Header from '../views/Header.vue'       // 顶部导航组件
import Home from '../views/Home.vue'           // 主内容区-首页
import Sidebar from '../views/Sidebar.vue'     // 侧边栏组件
import About from '../views/About.vue'         // 主内容区-关于页

const routes = [
  {
    path: '/',
    component: Layout,  // 使用包含多个 router-view 的布局组件
    children: [         // 子路由(用于填充命名视图)
      {
        path: '',       // 根路径(/)时匹配
        components: {   // 注意是 components(复数),关联命名视图
          default: Home,  // 默认视图(无 name)渲染 Home 组件
          main: About,    // 命名视图 main 渲染 About 组件
          sidebar: Sidebar // 命名视图 sidebar 渲染 Sidebar 组件
        }
      },
      {
        path: '/about',
        components: {
          default: Home,   // 主内容区仍用 Home(或其他组件)
          main: About,     // 主内容区渲染 About
          sidebar: Sidebar // 侧边栏保持不变
        }
      }
    ]
  }
]

const router = createRouter({
  history: createWebHistory(),
  routes
})

export default router

3. 验证效果

访问 //about时,布局组件 MainLayout.vue中的三个 <router-view>会分别渲染对应的组件:

  • 默认视图(无 name):渲染 Home.vue(根路径)或 Home.vue/about路径)。
  • 命名视图 main:渲染 About.vue
  • 命名视图 sidebar:始终渲染 Sidebar.vue(可根据需求动态调整)。

三、进阶用法:动态切换命名视图

命名视图的组件可以像普通路由一样动态切换,支持 <router-link>或编程式导航。

1. 使用 <router-link>切换

在布局组件中添加导航链接,通过 to指向不同子路由,触发命名视图的组件更新。

​示例(MainLayout.vue中添加导航)​​:

xml 复制代码
<template>
  <div class="main-layout">
    <!-- 导航链接 -->
    <nav>
      <router-link to="/">首页</router-link> | 
      <router-link to="/about">关于</router-link>
    </nav>

    <!-- 默认视图 -->
    <router-view></router-view>

    <!-- 命名视图 main -->
    <router-view name="main"></router-view>

    <!-- 命名视图 sidebar -->
    <router-view name="sidebar"></router-view>
  </div>
</template>

2. 编程式导航切换

通过 router.pushrouter.replace跳转到目标路由,触发命名视图更新。

​示例(在某个组件中)​​:

xml 复制代码
<script setup>
import { useRouter } from 'vue-router'

const router = useRouter()

// 跳转到 /about,触发命名视图更新
const goToAbout = () => {
  router.push('/about')
}
</script>

四、注意事项

1. 路由配置的层级关系

命名视图通常需要配合 ​​嵌套路由​​ 使用:

  • 父路由的 component是包含多个 <router-view>的布局组件。
  • 子路由的 components定义每个命名视图对应的具体组件。

2. 视图名称的唯一性

每个 <router-view>name必须唯一,否则会导致组件渲染冲突。

3. 嵌套视图的限制

若需要更复杂的嵌套结构(例如某个命名视图内部再嵌套其他视图),可以为嵌套的 <router-view>单独配置路由,但需注意层级深度。

4. 空视图的处理

若某个命名视图暂时不需要渲染内容,可以将其对应的组件设为 null或空组件:

yaml 复制代码
{
  path: '/empty',
  components: {
    main: null,  // 主内容区不渲染任何组件
    sidebar: Sidebar
  }
}

五、典型应用场景

命名视图适用于以下场景:

  • ​多栏布局​:如后台管理系统(左侧菜单 + 主内容区 + 顶部状态栏)。
  • ​复合页面​:如详情页(主内容 + 相关推荐 + 评论区)。
  • ​动态模块​:需要根据业务需求动态切换部分区域内容的场景。

通过命名视图,Vue Router 允许在一个页面中灵活组合多个路由组件,满足复杂布局的需求。核心是通过 components配置关联命名视图,并在模板中使用带 name<router-view>标签。

相关推荐
菠萝+冰6 分钟前
在 React 中,父子组件之间的通信(传参和传方法)
前端·javascript·react.js
庚云9 分钟前
一套代码如何同时适配移动端和pc端
前端
Jinuss10 分钟前
Vue3源码reactivity响应式篇Reflect和Proxy详解
前端·vue3
海天胜景18 分钟前
vue3 el-select 默认选中第一个
前端·javascript·vue.js
小小怪下士_---_37 分钟前
uniapp开发微信小程序自定义导航栏
前端·vue.js·微信小程序·小程序·uni-app
前端W39 分钟前
腾讯地图组件使用说明文档
前端
页面魔术41 分钟前
无虚拟dom怎么又流行起来了?
前端·javascript·vue.js
胡gh42 分钟前
如何聊懒加载,只说个懒可不行
前端·react.js·面试
Double__King1 小时前
巧用 CSS 伪元素,让背景图自适应保持比例
前端