Skip to content

项目结构

本文将详细介绍 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
  • 导出的类型定义以模块名开头(如:UserQueryUserInfo

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/:布局相关(如 useLayoutuseLayoutMenu
  • 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/            # 布局相关 hooks

src/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.username

src/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-importunplugin-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源码根目录
@/apisrc/apiAPI 目录
@/assetssrc/assets资源目录
@/componentssrc/components组件目录
@/utilssrc/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 注释
  • 为关键业务逻辑添加说明
  • 保持注释与代码同步

下一步

基于 MIT 许可发布