项目结构
本文档介绍 vue3-element-admin 的目录结构设计理念和组织方式。
架构选型
Vue 3 项目常见的架构模式有:
| 架构 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| 扁平结构 | 小型项目、PoC | 简单直接 | 不可扩展 |
| 原子设计 | 组件库 | 组件复用性高 | 层级复杂 |
| 模块化 | 中大型应用 | 松耦合、可维护 | 可能重复 |
| Feature-Sliced | 大型长期项目 | 高内聚、边界清晰 | 初期复杂 |
| 微前端 | 多团队协作 | 独立部署 | 协调成本高 |
本项目采用模块化架构,这是 Vue 3 应用最适合的架构方式:
- 按功能模块划分目录
- 模块间松耦合
- 便于独立开发和维护
- 可平滑演进到微前端
目录结构
vue3-element-admin/
├── mock/ # Mock 数据
├── public/ # 静态资源(不经过构建)
│ └── favicon.ico
├── src/
│ ├── api/ # API 接口层
│ │ ├── system/ # 系统管理模块
│ │ │ ├── user.ts
│ │ │ ├── role.ts
│ │ │ └── menu.ts
│ │ ├── auth.ts # 认证接口
│ │ └── file.ts # 文件接口
│ │
│ ├── assets/ # 静态资源(经过构建)
│ │ ├── icons/ # SVG 图标
│ │ └── images/ # 图片资源
│ │
│ ├── components/ # 公共组件
│ │ ├── AiAssistant/ # AI 助手
│ │ ├── Breadcrumb/ # 面包屑
│ │ ├── CommandPalette/ # 命令面板
│ │ ├── CopyButton/ # 复制按钮
│ │ ├── CURD/ # CURD 快速开发组件
│ │ ├── DictSelect/ # 字典选择器
│ │ ├── DictTag/ # 字典标签
│ │ ├── ECharts/ # 图表组件
│ │ ├── Fullscreen/ # 全屏切换
│ │ ├── Hamburger/ # 菜单折叠
│ │ ├── IconSelect/ # 图标选择器
│ │ ├── InputTag/ # 标签输入
│ │ ├── LangSelect/ # 语言选择
│ │ ├── NoticeDropdown/ # 通知下拉
│ │ ├── OperationColumn/ # 操作列
│ │ ├── Pagination/ # 分页组件
│ │ ├── SizeSelect/ # 尺寸选择
│ │ ├── TableSelect/ # 表格选择器
│ │ ├── TenantSwitcher/ # 租户切换
│ │ ├── TextScroll/ # 文字滚动
│ │ ├── ThemeSwitch/ # 主题切换
│ │ ├── Upload/ # 上传组件
│ │ └── WangEditor/ # 富文本编辑器
│ │
│ ├── composables/ # 组合式函数
│ │ ├── ai/ # AI 相关
│ │ │ └── useAiAction.ts
│ │ ├── table/ # 表格相关
│ │ │ └── useTableSelection.ts
│ │ ├── websocket/ # 实时通信相关(WebSocket)
│ │ │ ├── useStomp.ts
│ │ │ ├── useDictSync.ts
│ │ │ └── useOnlineCount.ts
│ │ └── index.ts # 统一导出
│ │
│ ├── constants/ # 常量定义
│ │ └── index.ts
│ │
│ ├── directives/ # 自定义指令
│ │ └── permission/ # 权限指令
│ │
│ ├── enums/ # 枚举定义
│ │ ├── api.ts # API 相关枚举
│ │ └── settings.ts # 设置相关枚举
│ │
│ ├── lang/ # 国际化
│ │ ├── package/ # 语言包
│ │ │ ├── zh-cn.json # 中文
│ │ │ └── en.json # 英文
│ │ ├── index.ts # 入口配置
│ │ └── utils.ts # 工具函数
│ │
│ ├── layouts/ # 布局组件
│ │ ├── components/ # 布局子组件
│ │ ├── index.vue # 主布局
│ │ └── useLayout.ts # 布局逻辑
│ │
│ ├── plugins/ # 插件配置
│ │ └── vxe-table.ts # VXE Table 配置
│ │
│ ├── router/ # 路由配置
│ │ ├── guards/ # 路由守卫
│ │ └── index.ts # 路由实例
│ │
│ ├── store/ # 状态管理
│ │ ├── modules/ # Store 模块
│ │ │ ├── user.ts
│ │ │ ├── app.ts
│ │ │ └── permission.ts
│ │ └── index.ts # Store 入口
│ │
│ ├── styles/ # 全局样式
│ │ ├── variables.scss # 变量定义
│ │ └── index.scss # 入口文件
│ │
│ ├── types/ # 类型定义
│ │ ├── api/ # API 类型
│ │ └── global.d.ts # 全局声明
│ │
│ ├── utils/ # 工具函数
│ │ ├── request.ts # HTTP 请求
│ │ ├── auth.ts # 认证工具
│ │ └── storage.ts # 存储工具
│ │
│ ├── views/ # 页面组件
│ │ ├── dashboard/ # 仪表盘
│ │ ├── demo/ # 功能演示
│ │ ├── system/ # 系统管理
│ │ │ ├── user/ # 用户管理
│ │ │ ├── role/ # 角色管理
│ │ │ └── menu/ # 菜单管理
│ │ └── login/ # 登录页
│ │
│ ├── App.vue # 根组件
│ ├── main.ts # 入口文件
│ └── settings.ts # 应用配置
│
├── tests/ # 测试文件
│ └── setup.ts # 测试配置
├── types/ # 全局类型声明
│
├── .env.development # 开发环境变量
├── .env.production # 生产环境变量
├── index.html # HTML 模板
├── package.json
├── tsconfig.json
├── uno.config.ts # UnoCSS 配置
├── vite.config.ts # Vite 配置
└── vitest.config.ts # Vitest 配置目录说明
api - 接口层
按业务模块组织 API 接口,单文件模块直接放在 api 根目录。
api/
├── system/ # 多文件模块用目录
│ ├── user.ts
│ └── role.ts
├── auth.ts # 单文件模块直接放根目录
└── file.tsassets - 静态资源
存放需要经过构建处理的静态资源。
assets/
├── icons/ # SVG 图标(通过 UnoCSS Icons 加载)
└── images/ # 图片资源(会被压缩优化)components - 公共组件
存放跨页面复用的公共组件,项目已重构为以下组件:
components/
├── AiAssistant/ # AI 助手组件
├── Breadcrumb/ # 面包屑导航
├── CommandPalette/ # 命令面板(快捷搜索)
├── CopyButton/ # 复制按钮
├── CURD/ # CURD 快速开发组件
│ ├── PageSearch.vue
│ ├── PageContent.vue
│ ├── PageModal.vue
│ ├── types.ts
│ └── usePage.ts
├── DictSelect/ # 字典选择器
├── DictTag/ # 字典标签
├── ECharts/ # 图表组件
├── Fullscreen/ # 全屏切换
├── Hamburger/ # 菜单折叠按钮
├── IconSelect/ # 图标选择器
├── InputTag/ # 标签输入
├── LangSelect/ # 语言选择
├── NoticeDropdown/ # 通知下拉
├── OperationColumn/ # 操作列
├── Pagination/ # 分页组件
├── SizeSelect/ # 尺寸选择
├── TableSelect/ # 表格选择器
├── TenantSwitcher/ # 租户切换
├── TextScroll/ # 文字滚动
├── ThemeSwitch/ # 主题切换
├── Upload/ # 上传组件
│ ├── FileUpload.vue
│ ├── MultiImageUpload.vue
│ └── SingleImageUpload.vue
└── WangEditor/ # 富文本编辑器命名规范:PascalCase,多词命名
composables - 组合式函数
存放可复用的组合式函数(Composition API)。
composables/
├── ai/
│ └── useAiAction.ts # AI 操作助手
├── table/
│ └── useTableSelection.ts # 表格选择管理
├── websocket/
│ ├── useStomp.ts # STOMP 协议
│ ├── useDictSync.ts # 字典同步
│ └── useOnlineCount.ts # 在线人数
└── index.ts # 统一导出命名规范:use 前缀 + camelCase
lang - 国际化
存放多语言配置和语言包。
lang/
├── package/
│ ├── zh-cn.json # 中文语言包
│ └── en.json # 英文语言包
├── index.ts # i18n 配置入口
└── utils.ts # 工具函数layouts - 布局组件
存放页面布局相关组件。
layouts/
├── components/ # 布局子组件
├── index.vue # 主布局入口
└── useLayout.ts # 布局逻辑store - 状态管理
使用 Pinia 进行状态管理,按功能模块拆分。
store/
├── modules/
│ ├── user.ts # 用户状态
│ ├── app.ts # 应用状态
│ ├── permission.ts # 权限状态
│ └── settings.ts # 设置状态
└── index.ts # 统一导出views - 页面组件
按路由/功能模块组织页面组件。
views/
├── dashboard/
│ └── index.vue
├── demo/ # 功能演示页面
│ ├── curd/
│ ├── dictionary.vue
│ ├── icons.vue
│ └── ...
├── system/
│ ├── user/
│ │ ├── index.vue
│ │ └── components/
│ └── role/
│ └── index.vue
└── login/
└── index.vue设计原则
1. 单一职责
每个目录只负责一类功能:
api/- 只放 API 接口utils/- 只放工具函数components/- 只放公共组件
2. 就近原则
页面私有组件放在页面目录下:
views/system/user/
├── index.vue
└── components/ # 只有 user 页面使用的组件
└── UserForm.vue3. 扁平优先
避免过深的目录嵌套,单文件模块不建目录:
# ✅ 好
api/auth.ts
# ❌ 不好
api/auth/index.ts # 只有一个文件,不需要目录4. 统一导出
每个模块目录提供 index.ts 统一导出:
typescript
// composables/index.ts
export * from "./table/useTableSelection";
export * from "./websocket";使用时:
typescript
import { useTableSelection, useDictSync } from "@/composables";模块依赖关系
views (页面)
↓
components (组件) + composables (组合函数)
↓
store (状态) + api (接口)
↓
utils (工具) + types (类型) + constants (常量)原则:上层可以依赖下层,下层不能依赖上层。
