源本科技 | 码上会

Vue3 嵌套路由

2026/04/23
18
0

引言

嵌套路由是 Vue Router 4 专为多层级布局应用设计的核心功能,通过树状结构实现父路由与子路由的关联映射。它可以让页面保持公共布局(如头部、侧边栏、底部)不变,仅动态切换核心内容区域,是后台管理系统、中台应用的标配路由方案。

/home/dashboard                       /home/products
+------------------+                  +-----------------+
| Home             |                  | Home            |
| +--------------+ |                  | +-------------+ |
| | Dashboard    | |  +------------>  | | Products    | |
| |              | |                  | |             | |
| +--------------+ |                  | +-------------+ |
+------------------+                  +-----------------+

嵌套路由概述

嵌套路由的核心逻辑:父路由组件保留固定布局,通过内置 <router-view> 渲染子路由对应的组件;子路由的路径无需书写完整父路径,路由系统会自动拼接。

例如访问 /home/dashboard,会渲染 Home 父组件,同时在其内部的 <router-view> 中渲染 Dashboard 子组件,实现布局复用与视图动态切换。

布局组件搭建

嵌套路由的基础是公共布局组件,我们基于 Vue 3 + Element Plus 搭建后台布局,作为父路由容器

根应用组件

修改 App.vue,作为整个应用的根容器:

<template>
  <!-- 根路由视图,渲染父级布局组件 -->
  <router-view />
</template>

<script setup lang="ts">
</script>

<style scoped>
</style>

主布局组件

创建 src/views/home/Home.vue,包含头部、侧边栏、内容区、底部,内容区通过 <router-view> 渲染子路由

<template>
  <el-container style="height: 100vh; box-sizing: border-box">
    <!-- 顶部 Header -->
    <el-header class="header">
      <h1>我的应用</h1>
    </el-header>

    <!-- 主体布局 -->
    <el-container>
      <!-- 侧边栏导航 -->
      <el-aside width="200px" class="aside">
        <el-menu router :default-active="route.path">
          <el-menu-item index="/home/dashboard">仪表盘</el-menu-item>
          <el-menu-item index="/home/products">产品列表</el-menu-item>
        </el-menu>
      </el-aside>

      <!-- 核心内容区:子路由渲染位置 -->
      <el-main class="main">
        <router-view />
      </el-main>
    </el-container>

    <!-- 底部 Footer -->
    <el-footer class="footer">
      <p>版权所有 © 2025</p>
    </el-footer>
  </el-container>
</template>

<script setup lang="ts">
import { useRoute } from 'vue-router';
// 获取当前路由,用于菜单激活
const route = useRoute();
</script>

<style scoped>
.header {
  background-color: #303133;
  color: #fff;
  padding: 0 20px;
  line-height: 60px;
}
.aside {
  background-color: #ebeef5;
}
.main {
  padding: 20px;
}
.footer {
  text-align: center;
  line-height: 60px;
  background-color: #f0f2f5;
  margin: 0;
}
</style>

嵌套路由核心配置

使用 children 配置项定义子路由,这是嵌套路由的核心语法;全局 404 路由必须放在最外层,不可嵌套在子路由中。

路由配置文件 src/router/index.ts

import { createRouter, createWebHashHistory, type RouteRecordRaw } from 'vue-router';
// 导入布局组件
import Home from '../views/home/Home.vue';
// 导入子路由组件
import Dashboard from '../views/home/Dashboard.vue';
import Products from '../views/home/Products.vue';
// 导入全局 404 组件
import NotFound from '../views/error/404.vue';

const routes: Array<RouteRecordRaw> = [
  {
    path: '/home',
    name: 'Home',
    component: Home,
    // 嵌套子路由配置
    children: [
      // 默认子路由:访问 /home 自动重定向到 /home/dashboard
      {
        path: '',
        redirect: '/home/dashboard'
      },
      // 子路由:路径无需加 /,自动拼接父路径 /home/dashboard
      {
        path: 'dashboard',
        name: 'Dashboard',
        component: Dashboard
      },
      {
        path: 'products',
        name: 'Products',
        component: Products
      }
    ]
  },
  // 根路径重定向,优化用户体验
  {
    path: '/',
    redirect: '/home'
  },
  // 全局 404 路由:必须放在配置最后(Vue Router 4 标准写法)
  {
    path: '/:catchAll(.*)',
    name: 'NotFound',
    component: NotFound
  }
];

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

export default router;

子路由组件实现

创建子路由对应的页面组件,用于渲染在布局的内容区域。

仪表盘组件

src/views/home/Dashboard.vue

<template>
  <div class="dashboard">
    <h2>仪表盘</h2>
    <p>欢迎来到后台管理仪表盘!</p>
  </div>
</template>

<script setup lang="ts">
</script>

<style scoped>
.dashboard {
  padding: 10px;
}
</style>

产品列表组件

src/views/home/Products.vue

<template>
  <div class="products">
    <h2>产品列表</h2>
    <ul>
      <li v-for="product in productList" :key="product.id">
        {{ product.name }}
      </li>
    </ul>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue';
// 模拟产品数据
const productList = ref([
  { id: 1, name: 'Vue 3 实战课程' },
  { id: 2, name: 'Vue Router 4 教程' },
  { id: 3, name: 'Element Plus 组件库' }
]);
</script>

<style scoped>
.products {
  padding: 10px;
}
li {
  margin: 10px 0;
}
</style>

404 异常组件

src/views/error/404.vue

<template>
  <div class="not-found">
    <h1>404 - 页面未找到</h1>
    <p>您访问的地址不存在,请检查后重试</p>
  </div>
</template>

<script setup lang="ts">
</script>

<style scoped>
.not-found {
  text-align: center;
  padding: 100px 0;
  color: #f56c6c;
}
</style>

嵌套路由核心规则

  1. 路径写法
    子路由 path 不需要以 / 开头,Vue Router 会自动拼接父路由路径;
    例:父路径 /home + 子路径 dashboard = 完整路径 /home/dashboard

  2. 默认子路由
    通过 redirect 配置重定向,访问父路由时自动跳转至子路由,提升用户体验。

  3. 视图渲染
    子路由组件只会渲染在父组件内部<router-view> 中,公共布局不会刷新。

  4. 路由优先级
    路由按定义顺序匹配,精确路由优先级高于通配符路由,404 路由必须放在最后

嵌套路由导航方式

声明式导航

<!-- 直接写完整路径 -->
<router-link to="/home/dashboard">仪表盘</router-link>
<!-- 推荐:命名路由(无硬编码,更易维护) -->
<router-link :to="{ name: 'Dashboard' }">仪表盘</router-link>

编程式导航

import { useRouter } from 'vue-router';
const router = useRouter();

// 跳转到产品列表
const goToProducts = () => {
  router.push('/home/products');
  // 推荐写法
  // router.push({ name: 'Products' });
};