语法大全-only-writer-two

Vue3 + TypeScript 项目中 Layout 骨架布局详解

你这段代码是Vue3 + Vue Router4 的路由配置,Layout 是项目的全局骨架布局组件 ,是整个后台管理系统的页面容器,所有子路由(项目页、图表页、编辑页等)都会渲染在这个布局内部。

一、Layout 的核心作用

  1. 固定全局结构:包含顶部导航栏、侧边菜单栏、底部版权栏等通用模块
  2. 路由视图承载 :提供 <router-view /> 插槽,渲染所有子页面
  3. 全局复用:避免每个页面重复写导航 / 菜单,只写业务内容

二、标准后台管理系统 Layout 结构(最常用)

这是企业级项目中最经典的 Layout 布局,直接对应你路由里的用法:

vue

复制代码
<!-- src/layout/index.vue -->
<template>
  <div class="app-layout">
    <!-- 1. 顶部导航栏(固定) -->
    <Header />

    <div class="layout-container">
      <!-- 2. 侧边菜单栏(固定,可折叠) -->
      <Sidebar />

      <!-- 3. 主内容区域(核心:子页面渲染在这里) -->
      <main class="app-main">
        <!-- 路由出口:所有 children 子路由都渲染在此处 -->
        <router-view v-slot="{ Component }">
          <keep-alive>
            <component :is="Component" />
          </keep-alive>
        </router-view>
      </main>
    </div>

    <!-- 4. 底部版权栏(可选) -->
    <Footer />
  </div>
</template>

<script setup lang="ts">
import { defineAsyncComponent } from 'vue'
// 引入布局子组件
import Header from './Header.vue'
import Sidebar from './Sidebar.vue'
import Footer from './Footer.vue'
</script>

<style scoped lang="scss">
.app-layout {
  height: 100vh;
  width: 100%;
  display: flex;
  flex-direction: column;
}
.layout-container {
  display: flex;
  flex: 1;
  overflow: hidden;
}
.app-main {
  flex: 1;
  overflow: auto; /* 内容超出滚动 */
  padding: 20px;
}
</style>

三、Layout 拆分的子组件(配套代码)

1. 顶部导航 Header.vue

vue

复制代码
<!-- src/layout/Header.vue -->
<template>
  <div class="header">
    <div class="logo">系统名称</div>
    <div class="header-right">
      <el-breadcrumb /> <!-- 面包屑导航 -->
      <user-info />     <!-- 用户信息/退出登录 -->
    </div>
  </div>
</template>

2. 侧边菜单 Sidebar.vue

vue

复制代码
<!-- src/layout/Sidebar.vue -->
<template>
  <div class="sidebar">
    <!-- 动态渲染路由菜单(根据路由配置自动生成) -->
    <el-menu
      :router="true"
      :default-active="$route.path"
      mode="vertical"
    >
      <sidebar-item v-for="route in routes" :key="route.path" :route="route" />
    </el-menu>
  </div>
</template>

3. 底部 Footer.vue

vue

复制代码
<!-- src/layout/Footer.vue -->
<template>
  <div class="footer">© 2025 版权所有</div>
</template>

四、和你路由配置的对应关系

ts

复制代码
const RootRoute: Array<RouteRecordRaw> = [
  {
    path: '/',
    name: 'Root',
    redirect: PageEnum.BASE_HOME,
    component: Layout,  // 全局骨架布局
    children: [        // 所有子页面 👇
      ...HttpErrorPage,// 404/500页面
      modules.projectRoutes, // 项目页
      modules.chartRoutes,   // 图表页
      modules.previewRoutes, // 预览页
      modules.editRoutes     // 编辑页
    ]
  }
]

渲染逻辑 :访问 /project → 加载 Layout 骨架 → 子路由页面渲染在 Layout 的 <router-view>

五、极简版 Layout(适合小型项目)

如果项目不需要复杂菜单,也可以用极简布局:

vue

复制代码
<!-- 极简 Layout -->
<template>
  <div class="simple-layout">
    <nav>顶部导航</nav>
    <div class="content">
      <router-view /> <!-- 子页面出口 -->
    </div>
  </div>
</template>

总结

  1. Layout 本质 :Vue 组件,是全局页面容器
  2. 核心结构:顶部导航 + 侧边菜单 + 主内容区(路由插槽)
  3. 核心功能:承载所有子路由,复用全局布局
  4. 你的项目中:所有业务页面(项目、图表、编辑)都嵌套在这个布局里展示

Vue 后台管理系统(你这种项目结构) 里,Layout 一定是放在 src/layout/ 文件夹下,这是行业统一规范,几乎所有项目都这么写。

我直接给你最标准、最准确的文件位置

1. Layout 组件的固定位置

plaintext

复制代码
src/
└── layout/
    ├── index.vue       # 👉 这就是你路由里用的 Layout 主文件
    ├── Header.vue      # 顶部导航
    ├── Sidebar.vue     # 侧边菜单
    ├── Footer.vue      # 底部
    └── ...其他布局组件

你路由里写的:

ts

复制代码
component: Layout,

对应的就是:src/layout/index.vue


2. 它是怎么被引入路由的?

在你的路由文件顶部,一定能看到这行导入:

ts

复制代码
// src/router/routes/index.ts 或类似路由文件
import Layout from '@/layout/index.vue'

@src 目录的别名,所以:

  • @/layout = src/layout
  • @/layout/index.vue = 骨架布局主文件

3. 你可以立刻在项目里找到它

按这个路径找,100% 能找到

plaintext

复制代码
你的项目根目录
 → src
   → layout
     → index.vue  ✅ 这就是 Layout 骨架布局

4. 小知识(为什么默认找 index.vue)

在 Vue / Vite 项目中:

ts

复制代码
import Layout from '@/layout'

不写文件名,默认会自动找 index.vue,所以路由里经常简写。


总结

  • Layout 位置src/layout/index.vue
  • 路由引入import Layout from '@/layout'
  • 作用:所有子页面的外层容器

() => import('@/views/chart/index.vue')不是单纯简化写法,是 路由懒加载

作用

  1. 项目初始启动时,不一次性加载所有页面代码
  2. 只有访问 /chart 这个路由时,才去请求、加载这个页面组件
  3. 减小首屏体积、加快项目打开速度、优化性能

对比记忆

  • 静态引入(一次性全加载,慢)

ts

复制代码
import Chart from '@/views/chart/index.vue'
  • 懒加载(用到再加载,企业项目标配)

ts

复制代码
component: () => import('xxx')

结合你人体骨架比喻

所有业务页面骨头,平时先休眠不加载只有你走到这个位置(访问路由),才唤醒这节骨骼,节省体力(性能)。

一句话总结

这两句导入 ,就是:把别人定义好的 "类型 / 常量" 拿过来用,让代码更规范、不容易写错、编辑器能智能提示。


逐行给你讲明白

1. import { RouteRecordRaw } from 'vue-router'

意思:

从 vue-router 官方库里,导入 "路由配置" 的标准类型。

作用:

你后面写路由数组时,必须符合这个类型规则

ts

复制代码
const routes: Array<RouteRecordRaw> = [ ... ]

它规定路由必须有:

  • path
  • name
  • component
  • children等等...

简单说:就是给路由 "定规矩",防止写错。


2. import { EditEnum } from '@/enums/pageEnum'

重点来了!

这句不是 "导入编辑门牌号",是你理解错了

我直接翻译:

  • Enum = 枚举(固定常量集合)
  • EditEnum = 跟 "编辑" 相关的一组常量(比如编辑页面路径、编辑类型)
  • @/enums/pageEnum.ts = 项目里统一存放 "页面枚举" 的文件

真实含义:

导入项目里定义好的、和【编辑功能】相关的常量。

比如它在文件里可能是这样:

ts

复制代码
// src/enums/pageEnum.ts
export enum EditEnum {
  BASE_EDIT = '/edit',       // 编辑页面路径
  EDIT_INFO = '/edit/info',
  EDIT_DETAIL = '/edit/detail'
}

为什么要用它?

为了不手写字符串

不使用枚举:

ts

复制代码
path: '/edit'

容易写错,比如写成 /editt/eidt

使用枚举:

ts

复制代码
path: EditEnum.BASE_EDIT

编辑器会自动提示,永远不会写错!


最通俗的比喻(秒懂版)

  • RouteRecordRaw = 官方给你的路由说明书
  • EditEnum = 项目里统一规定好的编辑相关 "代号表"

你导入它们,就是:拿说明书 + 拿代号表,来规范写路由。


最终大白话总结

  1. RouteRecordRaw规定路由怎么写才合法
  2. EditEnum使用项目统一定义的编辑路径 / 常量,避免手写出错

🦴 一句话定位

这是 → 【项目模块】的路由(一大段主骨骼)

不是一节骨头,是一整段带关节的肋骨 + 脊椎! 因为它里面有 children 子路由


逐段超快看懂(你全会!)

1. 导入 + 懒加载(4 个页面)

ts

复制代码
const importPath = {
  'PageEnum.BASE_HOME_NAME': () => import('@/views/project/index.vue'),
  'PageEnum.BASE_HOME_ITEMS_NAME': () => import('@/views/project/items/index.vue'),
  'PageEnum.BASE_HOME_TEMPLATE_NAME': () => import('@/views/project/mtTemplate/index.vue'),
  'PageEnum.BASE_HOME_TEMPLATE_MARKET_NAME': () => import('@/views/project/templateMarket/index.vue')
}

✅ 懒加载✅ 4 个页面:项目首页、我的项目、我的模板、模板市场✅ 全部用到时才加载,速度快


🔥 核心:这是一个嵌套路由(父 + 子)

ts

复制代码
const projectRoutes: RouteRecordRaw = {
  path: '/project',       // 父路由
  name: 'Project',
  component: 项目外壳,
  redirect: '/my-project', // 重定向
  meta: { title: '项目', isRoot: true },
  
  // 👇👇👇 重点在这里!子路由!
  children: [
    { path: '/my-project', component: 我的项目 },
    { path: '/my-template', component: 我的模板 },
    { path: '/template-market', component: 模板市场 },
  ]
}

🔥 两个超级关键的点(你一看就懂)

1. redirect: PageEnum.BASE_HOME_ITEMS

进入 /project → 自动跳转到 /my-project人话:

你进了 "项目" 这个大门,自动把你带到 "我的项目"

2. children: [] 子路由

这是真正的嵌套骨架!

  • 父页面:project/index.vue(外壳)
  • 子页面:在外壳内部显示
  • 肋骨挂在脊椎上一样

🎯 这个路由的结构(最清晰)

plaintext

复制代码
/project               父页面(外壳)
  ├── /my-project      子页面 → 我的项目
  ├── /my-template     子页面 → 我的模板
  └── /template-market 子页面 → 模板市场

这就是企业级最标准的嵌套路由!


✅ 你现在彻底掌握了:

  1. 基础路由(图表、编辑、预览)
  2. 嵌套路由(项目模块,带 children)
  3. 重定向 redirect
  4. 路由懒加载
  5. meta 配置(isRoot /title)

🦴 整个路由骨架 → 100% 全部学完!

我给你做终极一句话总结

路由 = 人体骨架

  • index.ts = 脊椎主干
  • 守卫 = 神经保安
  • modules = 一节节业务骨头
  • children = 嵌套小骨头
  • 懒加载 = 节省体力
  • redirect = 自动指路
  • isRoot = 主骨标记

你现在 真的、完全、彻底吃透路由了!

相关推荐
一袋米扛几楼981 小时前
【报错问题】彻底解决 TypeScript 报错 TS2769: No overload matches this call (JWT 篇)
linux·javascript·typescript
huangql5201 小时前
浏览器 Location API、History API、路由记录与支付跳转完全指南
前端
木斯佳1 小时前
前端八股文面经大全:腾讯前端实习一面(2026-04-27)·面经深度解析
前端·八股·面经
sayamber1 小时前
Kubernetes 生产环境避坑指南:10 个真实故障案例与解决方案
前端
清寒_2 小时前
分层理解AI架构,降低对AI复杂度的恐惧
前端·人工智能·ai编程
李白的天不白2 小时前
如何项目发布到github上
android·vue.js
牧码岛2 小时前
Web前端之JavaScrip中的Array、Object、Map和Set详解
前端·javascript·web·web前端
Bigger2 小时前
😮‍💨 有了 AI 之后,我怎么感觉反而更累了?
前端·aigc·ai编程
Dxy12393102162 小时前
HTML中使用Canvas动态图形渲染:解锁Web交互新维度
前端·html·图形渲染