项目结构
本文将详细介绍 vue3-element-admin 的项目结构和各个目录的作用。
目录结构
vue3-element-admin/
├── .husky/ # Git hooks 配置
├── .vscode/ # VSCode 配置
├── mock/ # Mock 数据
├── public/ # 静态资源(不会被编译)
├── src/
│ ├── api/ # API 接口
│ ├── assets/ # 静态资源(会被编译)
│ │ ├── icons/ # SVG 图标
│ │ ├── images/ # 图片资源
│ │ └── styles/ # 全局样式
│ ├── components/ # 全局组件
│ │ ├── AiAssistant/ # AI 助手
│ │ ├── CURD/ # CURD 快速开发组件
│ │ ├── Dict/ # 字典组件
│ │ ├── IconSelect/ # 图标选择器
│ │ ├── Upload/ # 上传组件
│ │ └── ... # 其他组件
│ ├── composables/ # 组合式函数
│ │ ├── auth/ # 认证相关
│ │ ├── layout/ # 布局相关
│ │ ├── websocket/ # WebSocket 相关
│ │ └── ... # 其他组合式函数
│ ├── directives/ # 自定义指令
│ ├── enums/ # 枚举
│ ├── lang/ # 国际化语言包
│ ├── layout/ # 布局组件
│ ├── plugins/ # 插件
│ ├── router/ # 路由配置
│ ├── store/ # Pinia 状态管理
│ ├── types/ # TypeScript 类型定义
│ ├── utils/ # 工具函数
│ ├── views/ # 页面组件
│ │ ├── demo/ # 示例页面
│ │ ├── system/ # 系统管理
│ │ └── ... # 其他页面
│ ├── App.vue # 根组件
│ └── main.ts # 入口文件
├── .env.development # 开发环境变量
├── .env.production # 生产环境变量
├── .eslintrc.cjs # ESLint 配置
├── .prettierrc.cjs # Prettier 配置
├── .stylelintrc.cjs # Stylelint 配置
├── index.html # HTML 入口
├── package.json # 项目依赖
├── tsconfig.json # TypeScript 配置
├── vite.config.ts # Vite 配置
└── README.md # 项目说明核心目录说明
src/api
存放所有 API 接口定义,按业务模块划分:
typescript
// src/api/user.ts
import request from '@/utils/request'
// 获取用户列表
export function getUserList(params: UserQuery) {
return request({
url: '/api/v1/users',
method: 'get',
params
})
}命名规范:
- 文件名使用小写字母和连字符(如:
user-role.ts) - 函数名使用驼峰命名(如:
getUserList) - 导出的类型定义以模块名开头(如:
UserQuery、UserInfo)
src/assets
存放静态资源文件:
- icons/:SVG 图标文件
- images/:图片资源
- styles/:全局样式文件
index.scss:样式入口variables.scss:CSS 变量mixins.scss:混入transition.scss:过渡动画
src/components
全局共享组件,可在任何页面中直接使用:
vue
<template>
<!-- 自动导入,无需手动 import -->
<IconSelect v-model="icon" />
</template>组件分类:
- 业务组件:如 CURD、Upload、IconSelect 等
- 布局组件:如 Breadcrumb、Hamburger 等
- 功能组件:如 AiAssistant、MenuSearch 等
src/composables
组合式函数(Composables),提供可复用的逻辑:
typescript
// 使用示例
import { useTokenRefresh } from '@/composables'
const { startRefresh, stopRefresh } = useTokenRefresh()分类:
- auth/:认证相关(如
useTokenRefresh) - layout/:布局相关(如
useLayout、useLayoutMenu) - websocket/:WebSocket 相关(如
useStomp)
src/directives
自定义指令:
typescript
// src/directives/permission.ts
export default {
mounted(el: HTMLElement, binding: DirectiveBinding) {
// 权限判断逻辑
}
}使用:
vue
<el-button v-hasPerm="['sys:user:add']">新增</el-button>src/enums
枚举定义:
typescript
// src/enums/CommonEnum.ts
export enum StatusEnum {
ENABLE = 1,
DISABLE = 0
}src/lang
国际化语言包:
lang/
├── index.ts # 国际化配置
├── zh-cn.ts # 中文语言包
└── en.ts # 英文语言包src/layout
布局组件,包含不同的布局方式:
layout/
├── components/ # 布局子组件
│ ├── AppMain.vue # 主内容区
│ ├── Navbar.vue # 顶部导航
│ ├── Sidebar/ # 侧边栏
│ └── ...
├── index.vue # 布局入口
└── hooks/ # 布局相关 hookssrc/router
路由配置:
router/
├── index.ts # 路由入口
├── routes.ts # 静态路由
└── modules/ # 路由模块
├── system.ts # 系统管理路由
└── ...路由配置示例:
typescript
{
path: '/user',
component: Layout,
meta: { title: '用户管理', icon: 'user' },
children: [
{
path: 'list',
component: () => import('@/views/user/list.vue'),
meta: { title: '用户列表', keepAlive: true }
}
]
}src/store
Pinia 状态管理:
store/
├── index.ts # Store 入口
├── modules/ # Store 模块
│ ├── user.ts # 用户信息
│ ├── permission.ts # 权限信息
│ ├── settings.ts # 系统设置
│ └── ...
└── types/ # Store 类型定义使用示例:
typescript
import { useUserStore } from '@/store/modules/user'
const userStore = useUserStore()
const username = userStore.usernamesrc/utils
工具函数库:
utils/
├── request.ts # Axios 封装
├── auth.ts # 认证工具
├── dict.ts # 字典工具
├── permission.ts # 权限工具
├── storage.ts # 本地存储
└── ...src/views
页面组件,按业务模块划分:
views/
├── dashboard/ # 控制台
├── system/ # 系统管理
│ ├── user/ # 用户管理
│ ├── role/ # 角色管理
│ ├── menu/ # 菜单管理
│ └── ...
├── demo/ # 示例页面
└── ...页面命名:
- 使用小写字母和连字符
- 文件名与路由路径保持一致
- 页面组件建议放在独立目录中
配置文件说明
package.json
项目依赖和脚本配置:
json
{
"scripts": {
"dev": "vite", // 启动开发服务器
"build": "vite build", // 构建生产环境
"preview": "vite preview", // 预览生产构建
"lint": "...", // 代码检查
"commit": "git-cz" // 交互式提交
}
}vite.config.ts
Vite 构建配置:
- 路径别名配置
- 插件配置(自动导入、组件自动注册等)
- 代理配置
- 构建优化配置
tsconfig.json
TypeScript 编译配置:
- 编译选项
- 路径映射
- 类型声明文件
.env.*
环境变量配置:
bash
# .env.development
VITE_APP_API_URL = https://api.youlai.tech
VITE_MOCK_DEV_SERVER = false自动导入
项目使用 unplugin-auto-import 和 unplugin-vue-components 实现自动导入:
API 自动导入
Vue 3、Vue Router、Pinia 等 API 无需手动导入:
typescript
// 无需导入,直接使用
const count = ref(0)
const route = useRoute()
const router = useRouter()组件自动导入
全局组件和 Element Plus 组件无需注册和导入:
vue
<template>
<!-- 自动导入,直接使用 -->
<el-button>按钮</el-button>
<IconSelect v-model="icon" />
</template>别名配置
项目配置了常用的路径别名:
| 别名 | 路径 | 说明 |
|---|---|---|
@ | src | 源码根目录 |
@/api | src/api | API 目录 |
@/assets | src/assets | 资源目录 |
@/components | src/components | 组件目录 |
@/utils | src/utils | 工具目录 |
使用示例:
typescript
import { getUserList } from '@/api/user'
import logo from '@/assets/logo.png'代码规范
项目集成了完整的代码规范工具链:
- ESLint:JavaScript/TypeScript 代码检查
- Prettier:代码格式化
- Stylelint:样式代码检查
- EditorConfig:编辑器配置统一
- Husky:Git hooks
- Commitlint:提交信息规范
最佳实践
1. 文件命名
- 组件:使用 PascalCase(如:
UserList.vue) - 工具函数:使用 camelCase(如:
formatDate.ts) - 页面:使用 kebab-case(如:
user-list.vue)
2. 组件拆分
- 超过 300 行的组件应该拆分
- 将可复用的部分抽取为独立组件
- 将复杂逻辑抽取为组合式函数
3. 类型定义
- 为 API 接口定义类型
- 为组件 props 定义类型
- 避免使用
any类型
4. 代码注释
- 为复杂函数添加 JSDoc 注释
- 为关键业务逻辑添加说明
- 保持注释与代码同步
