Vue3 零基础每日笔记(048):嵌套路由与命名视图——后台管理系统布局雏形

一、前言

后台管理系统的标准长相:顶栏 + 侧边菜单 + 内容区,点菜单只有内容区变 ,顶栏侧栏纹丝不动。这就是嵌套路由的战场:路由里套路由,页面里套页面。本篇用 children 配置搭出后台布局雏形,顺带认识命名视图。

二、嵌套路由:路由里套路由

场景:/admin 下的"个人资料"和"系统设置"两个子页面,共享一个后台布局。

ts 复制代码
// src/router/index.ts
import AdminLayout from '@/views/AdminLayout.vue'

const routes = [
  {
    path: '/admin',
    component: AdminLayout,          // 父路由:布局页
    children: [                      // ★ 子路由数组
      {
        // 注意:子路由 path 不以 / 开头(相对父路径)
        path: 'profile',
        name: 'admin-profile',
        component: () => import('@/views/admin/ProfileView.vue')
      },
      {
        path: 'settings',
        name: 'admin-settings',
        component: () => import('@/views/admin/SettingsView.vue')
      }
    ]
  }
]

父组件 AdminLayout 里挖第二个出口

vue 复制代码
<!-- src/views/AdminLayout.vue -->
<template>
  <div class="admin">
    <aside class="side">
      <h3>后台管理</h3>
      <!-- 子路由链接:to 写完整路径 -->
      <RouterLink to="/admin/profile">个人资料</RouterLink>
      <RouterLink to="/admin/settings">系统设置</RouterLink>
    </aside>

    <main class="content">
      <!-- 二号出口:子路由组件渲染在这里 -->
      <RouterView />
    </main>
  </div>
</template>

<style scoped>
.admin { display: flex; min-height: 200px; border: 1px solid #eee; }
.side { width: 140px; background: #f5f5f5; padding: 12px; display: flex; flex-direction: column; gap: 8px; }
.content { flex: 1; padding: 16px; }
</style>

结构一层套一层:URL /admin/profile 匹配 AdminLayout → 其内部 RouterView 再渲染 ProfileView。子路由的出口永远在父组件的 RouterView 里 ------访问 /admin/profile 时 App.vue 的出口渲染 AdminLayout,AdminLayout 的出口渲染 ProfileView,两层同时渲染

【截图位置:点击侧边菜单只有内容区变化的效果】

三、两个必会细节:默认子路由与"不写 /"

1. 子路由 path 不以 / 开头path: 'profile' 相对拼接成 /admin/profile。写了 /profile 会变成顶级路由 /profile(脱离父布局)------子路由斜杠必须省,这是新人第一大坑。

2. 默认子路由 :访问 /admin(不带子路径)时显示什么?给 children 加一条空 path 的子路由:

ts 复制代码
children: [
  {
    path: '',                    // 空字符串 = 默认子路由
    redirect: { name: 'admin-profile' }   // 方案 A:重定向到 profile
  },
  {
    path: 'profile',
    name: 'admin-profile',
    component: () => import('@/views/admin/ProfileView.vue')
  },
  // ...
]

或者直接给空 path 配组件(/admin 本身就渲染 profile 内容):

ts 复制代码
{
  path: '',                       // 方案 B:/admin 直接渲染默认页
  name: 'admin-home',
  component: () => import('@/views/admin/ProfileView.vue')
}

方案 A(redirect)语义更清晰,企业里常用。

四、多级嵌套:children 里还有 children

ts 复制代码
{
  path: '/admin',
  component: AdminLayout,
  children: [
    {
      path: 'settings',
      component: () => import('@/views/admin/SettingsView.vue'),
      children: [
        { path: 'basic', component: () => import('@/views/admin/SettingsBasic.vue') },
        { path: 'safe', component: () => import('@/views/admin/SettingsSafe.vue') }
      ]
    }
  ]
}

SettingsView 里再放一个 RouterView 渲染 basic/safe。三层结构 = 三个 RouterView 同时渲染。嵌套别超过三四层(024 篇套娃警告在路由里同样生效),太深说明信息架构有问题。

五、命名视图:一个页面多个出口

嵌套路由是"父子关系",命名视图是"兄弟并排"------同一层挖几个坑,按名字填:

ts 复制代码
// 同一个 path,配多个组件
{
  path: '/dashboard',
  components: {                   // ★ 注意 components 复数
    default: () => import('@/views/dash/MainView.vue'),   // 无名出口
    sidebar: () => import('@/views/dash/SideView.vue'),   // 名叫 sidebar 的出口
    header: () => import('@/views/dash/HeaderView.vue')   // 名叫 header 的出口
  }
}
vue 复制代码
<!-- 模板里按名字认领 -->
<template>
  <RouterView name="header" />
  <div class="row">
    <RouterView name="sidebar" />
    <RouterView />   <!-- 不写 name = default -->
  </div>
</template>

使用频率不高(布局通常一个出口够用),但 el-container 布局 + 多区域路由的场景会遇到,认识即可。

六、综合实战:后台布局雏形(完整代码)

把默认子路由 + 侧边菜单 + 内容区整合成可运行版本:

ts 复制代码
// src/router/index.ts
import { createRouter, createWebHistory } from 'vue-router'
import AdminLayout from '@/views/AdminLayout.vue'

const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes: [
    { path: '/', name: 'home', component: () => import('@/views/HomeView.vue') },
    {
      path: '/admin',
      component: AdminLayout,
      children: [
        { path: '', redirect: { name: 'admin-profile' } },
        {
          path: 'profile',
          name: 'admin-profile',
          component: () => import('@/views/admin/ProfileView.vue')
        },
        {
          path: 'settings',
          name: 'admin-settings',
          component: () => import('@/views/admin/SettingsView.vue')
        }
      ]
    }
  ]
})

export default router
vue 复制代码
<!-- src/views/admin/ProfileView.vue -->
<template><h4>👤 个人资料页</h4><p>只有内容区在变</p></template>
vue 复制代码
<!-- src/views/admin/SettingsView.vue -->
<template><h4>⚙️ 系统设置页</h4><p>顶栏侧栏毫无反应</p></template>

AdminLayout 用第四节那份(含样式)。跑起来:/admin 自动重定向到 profile,点菜单切换子页面,布局层稳如泰山------这就是 068 篇后台骨架的地基。

【截图位置:/admin 默认进入 profile、切换 settings 的运行效果】

七、踩坑记录

  1. 子路由 path 带了 /path: '/profile' 变成顶级路由,脱离父布局,访问 /admin/profile 匹配不到------子路由一律省斜杠
  2. 忘了在父组件放 RouterView:子路由匹配成功但页面只显示布局、内容空白------父组件没挖坑
  3. RouterLink 的 to 写了相对路径<RouterLink to="profile"> 在嵌套里行为随当前 URL 变化,容易错------to 永远写完整路径或按 name 跳
  4. 默认子路由写成 path: '/' :空 path 是 '','/' 在 children 里是非法/诡异行为
  5. components 单复数搞混 :命名视图用 components(复数)+ RouterView name;普通嵌套用 component(单数)

八、今日小结

  • children 嵌套:父组件里挖第二个 RouterView,子路由 path 不带 /、to 写全路径
  • 默认子路由:空 path + redirect(或直接配组件)
  • 多级嵌套 = 多层出口同时渲染,控制在三四层内
  • 命名视图:components 复数 + RouterView name,同级多出口(低频,认识即可)

下篇预告

后台布局有了,但谁都能访问 /admin 吗?下一篇 049 路由守卫------全局前置守卫、路由独享守卫、组件内守卫三级关卡,手写登录拦截完整流程。

相关推荐
Mr.Meng_951 小时前
彻底搞懂Promise.allSettled:用法、场景、源码手写、面试题详解
前端
心易行者1 小时前
Python在线运行+SQLite数据库实战:0成本搭个人数据后台,5个场景直接套用
前端·网络·人工智能·python
雪芽蓝域zzs1 小时前
第 10 章:大屏看板自动轮播高亮(ECharts 大屏经典效果)
vue.js·echars
@tangguo1232 小时前
npm 和 yarn 配置说明
前端·javascript·npm·node.js·yarn
摇滚侠2 小时前
《Spring Boot 3:高级与架构设计》第 2 章 IOC容器的高级机制 BeanFactoryPostProcessor 个人理解 6
java·spring boot·笔记·后端
zhiyouTech2 小时前
GEO实战:把生成式引擎优化当成检索工程来做(含五断点诊断与50题Benchmark)
前端·人工智能
M78佐菲2 小时前
ARM学习笔记(五)
linux·arm开发·笔记·嵌入式硬件·学习
志尊宝2 小时前
Vue3 零基础每日笔记(052):路由常见坑一次排雷——404、刷新丢参数、部署白屏
前端·javascript·vue.js·笔记·html5
linux_cfan2 小时前
videojs v10 源代码系列解读:13 · 能力型媒体契约:`Media` 的组合接口
前端·javascript·音视频