Vue3 + TypeScript 项目目录结构
📁 项目根目录
项目名称/
├── .vscode/ # VSCode 配置
│ ├── settings.json # 编辑器设置
│ └── extensions.json # 推荐扩展
├── .husky/ # Git hooks
│ └── pre-commit # 提交前检查
├── public/ # 静态资源(不经过打包)
│ ├── favicon.ico
│ └── index.html
├── src/ # 源代码目录
│ ├── api/ # API 接口管理
│ │ ├── modules/ # 按模块划分的接口
│ │ │ ├── user.ts
│ │ │ ├── order.ts
│ │ │ └── product.ts
│ │ ├── request.ts # axios 封装
│ │ ├── types.ts # API 类型定义
│ │ └── index.ts # 统一导出
│ │
│ ├── assets/ # 静态资源(经过打包)
│ │ ├── images/ # 图片资源
│ │ │ ├── common/ # 公共图片
│ │ │ └── icons/ # 图标
│ │ ├── fonts/ # 字体文件
│ │ └── styles/ # 全局样式
│ │ ├── variables.scss # SCSS 变量
│ │ ├── mixins.scss # SCSS 混入
│ │ ├── reset.scss # 样式重置
│ │ └── index.scss # 样式入口
│ │
│ ├── components/ # 公共组件
│ │ ├── common/ # 通用基础组件
│ │ │ ├── Button/
│ │ │ │ ├── Button.vue
│ │ │ │ └── index.ts
│ │ │ ├── Input/
│ │ │ │ ├── Input.vue
│ │ │ │ └── index.ts
│ │ │ └── Table/
│ │ │ ├── Table.vue
│ │ │ └── index.ts
│ │ │
│ │ ├── business/ # 业务组件
│ │ │ ├── UserCard/ # 用户卡片组件
│ │ │ │ ├── UserCard.vue
│ │ │ │ ├── components/ # 子组件
│ │ │ │ │ ├── UserAvatar.vue
│ │ │ │ │ ├── UserInfo.vue
│ │ │ │ │ └── UserActions.vue
│ │ │ │ ├── composables/ # 组件相关 hooks(逻辑复杂时使用)
│ │ │ │ │ └── useUserCard.ts
│ │ │ │ ├── styles/ # 组件样式(样式过长时抽离)
│ │ │ │ │ └── index.scss
│ │ │ │ └── index.ts
│ │ │ │
│ │ │ ├── OrderList/ # 订单列表组件
│ │ │ │ ├── OrderList.vue
│ │ │ │ ├── components/
│ │ │ │ │ ├── OrderItem.vue
│ │ │ │ │ ├── OrderStatus.vue
│ │ │ │ │ └── OrderActions.vue
│ │ │ │ ├── composables/
│ │ │ │ │ └── useOrderList.ts
│ │ │ │ ├── styles/
│ │ │ │ │ └── index.scss
│ │ │ │ └── index.ts
│ │ │ │
│ │ │ └── ProductCard/ # 商品卡片组件
│ │ │ ├── ProductCard.vue
│ │ │ ├── components/
│ │ │ │ ├── ProductImage.vue
│ │ │ │ ├── ProductPrice.vue
│ │ │ │ └── ProductTags.vue
│ │ │ ├── composables/
│ │ │ │ └── useProductCard.ts
│ │ │ ├── styles/
│ │ │ │ └── index.scss
│ │ │ └── index.ts
│ │ │
│ │ └── layout/ # 布局组件
│ │ ├── Header/
│ │ │ ├── Header.vue
│ │ │ ├── components/
│ │ │ │ ├── NavMenu.vue
│ │ │ │ ├── UserDropdown.vue
│ │ │ │ └── SearchBar.vue
│ │ │ ├── composables/
│ │ │ │ └── useHeader.ts
│ │ │ ├── styles/
│ │ │ │ └── index.scss
│ │ │ └── index.ts
│ │ │
│ │ ├── Sidebar/
│ │ │ ├── Sidebar.vue
│ │ │ ├── components/
│ │ │ │ └── MenuItem.vue
│ │ │ ├── composables/
│ │ │ │ └── useSidebar.ts
│ │ │ ├── styles/
│ │ │ │ └── index.scss
│ │ │ └── index.ts
│ │ │
│ │ └── Footer/
│ │ ├── Footer.vue
│ │ ├── styles/
│ │ │ └── index.scss
│ │ └── index.ts
│ │
│ ├── composables/ # 组合式函数(Hooks)
│ │ ├── useAuth.ts # 认证相关
│ │ ├── useTable.ts # 表格相关
│ │ ├── useForm.ts # 表单相关
│ │ ├── usePagination.ts # 分页相关
│ │ ├── useRequest.ts # 请求相关
│ │ ├── usePermission.ts # 权限相关
│ │ ├── useDebounce.ts # 防抖
│ │ ├── useThrottle.ts # 节流
│ │ ├── useLocalStorage.ts # 本地存储
│ │ └── index.ts # 统一导出
│ │
│ ├── directives/ # 自定义指令
│ │ ├── v-loading.ts
│ │ ├── v-permission.ts
│ │ └── index.ts
│ │
│ ├── plugins/ # 插件配置
│ │ ├── element-plus.ts # Element Plus 配置
│ │ ├── pinia.ts # Pinia 配置
│ │ └── index.ts
│ │
│ ├── router/ # 路由配置
│ │ ├── modules/ # 路由模块
│ │ │ ├── user.ts
│ │ │ ├── order.ts
│ │ │ └── product.ts
│ │ ├── index.ts # 路由入口
│ │ ├── guards.ts # 路由守卫
│ │ └── types.ts # 路由类型
│ │
│ ├── stores/ # Pinia 状态管理
│ │ ├── modules/ # 状态模块
│ │ │ ├── user.ts # 用户状态
│ │ │ ├── app.ts # 应用状态
│ │ │ ├── permission.ts # 权限状态
│ │ │ └── order.ts # 订单状态
│ │ └── index.ts # Store 入口
│ │
│ ├── views/ # 页面级组件(业务页面)
│ │ ├── login/ # 登录页面
│ │ │ ├── Login.vue
│ │ │ ├── components/ # 页面级子组件
│ │ │ │ ├── LoginForm.vue
│ │ │ │ └── LoginHeader.vue
│ │ │ ├── composables/ # 页面级 hooks(逻辑复杂时使用)
│ │ │ │ └── useLogin.ts
│ │ │ ├── styles/ # 页面样式(样式过长时抽离)
│ │ │ │ └── index.scss
│ │ │ └── index.ts
│ │ │
│ │ ├── dashboard/ # 仪表盘页面
│ │ │ ├── Dashboard.vue
│ │ │ ├── components/
│ │ │ │ ├── StatCard.vue
│ │ │ │ ├── ChartCard.vue
│ │ │ │ └── RecentActivity.vue
│ │ │ ├── composables/
│ │ │ │ └── useDashboard.ts
│ │ │ ├── styles/
│ │ │ │ └── index.scss
│ │ │ └── index.ts
│ │ │
│ │ ├── user/ # 用户管理页面
│ │ │ ├── index.vue # 用户列表
│ │ │ ├── components/
│ │ │ │ ├── UserTable.vue
│ │ │ │ ├── UserSearch.vue
│ │ │ │ └── UserDialog.vue
│ │ │ ├── composables/
│ │ │ │ └── useUserManagement.ts
│ │ │ ├── styles/
│ │ │ │ └── index.scss
│ │ │ │
│ │ │ ├── detail/ # 用户详情子页面
│ │ │ │ ├── UserDetail.vue
│ │ │ │ ├── components/
│ │ │ │ │ ├── UserInfo.vue
│ │ │ │ │ └── UserHistory.vue
│ │ │ │ ├── composables/
│ │ │ │ │ └── useUserDetail.ts
│ │ │ │ └── styles/
│ │ │ │ └── index.scss
│ │ │ │
│ │ │ └── edit/ # 用户编辑子页面
│ │ │ ├── UserEdit.vue
│ │ │ ├── components/
│ │ │ │ └── UserForm.vue
│ │ │ ├── composables/
│ │ │ │ └── useUserEdit.ts
│ │ │ └── styles/
│ │ │ └── index.scss
│ │ │
│ │ ├── order/ # 订单管理页面
│ │ │ ├── index.vue # 订单列表
│ │ │ ├── components/
│ │ │ │ ├── OrderTable.vue
│ │ │ │ ├── OrderFilter.vue
│ │ │ │ └── OrderDetailDialog.vue
│ │ │ ├── composables/
│ │ │ │ └── useOrderManagement.ts
│ │ │ ├── styles/
│ │ │ │ └── index.scss
│ │ │ │
│ │ │ └── detail/ # 订单详情子页面
│ │ │ ├── OrderDetail.vue
│ │ │ ├── components/
│ │ │ │ ├── OrderInfo.vue
│ │ │ │ ├── OrderItems.vue
│ │ │ │ └── OrderTimeline.vue
│ │ │ ├── composables/
│ │ │ │ └── useOrderDetail.ts
│ │ │ └── styles/
│ │ │ └── index.scss
│ │ │
│ │ └── product/ # 商品管理页面
│ │ ├── index.vue # 商品列表
│ │ ├── components/
│ │ │ ├── ProductTable.vue
│ │ │ ├── ProductSearch.vue
│ │ │ └── ProductDialog.vue
│ │ ├── composables/
│ │ │ └── useProductManagement.ts
│ │ ├── styles/
│ │ │ └── index.scss
│ │ │
│ │ └── detail/ # 商品详情子页面
│ │ ├── ProductDetail.vue
│ │ ├── components/
│ │ │ ├── ProductInfo.vue
│ │ │ ├── ProductGallery.vue
│ │ │ └── ProductSpecs.vue
│ │ ├── composables/
│ │ │ └── useProductDetail.ts
│ │ └── styles/
│ │ └── index.scss
│ │
│ ├── utils/ # 工具函数
│ │ ├── format.ts # 格式化工具
│ │ ├── validate.ts # 验证工具
│ │ ├── date.ts # 日期工具
│ │ ├── storage.ts # 存储工具
│ │ ├── common.ts # 通用工具
│ │ └── index.ts
│ │
│ ├── types/ # TypeScript 类型定义
│ │ ├── api.ts # API 类型
│ │ ├── user.ts # 用户类型
│ │ ├── order.ts # 订单类型
│ │ ├── product.ts # 商品类型
│ │ ├── common.ts # 通用类型
│ │ └── index.ts
│ │
│ ├── constants/ # 常量定义
│ │ ├── api.ts # API 常量
│ │ ├── status.ts # 状态常量
│ │ └── index.ts
│ │
│ ├── config/ # 配置文件
│ │ ├── index.ts # 配置入口
│ │ └── env.ts # 环境配置
│ │
│ ├── enums/ # 枚举定义
│ │ ├── status.ts # 状态枚举
│ │ ├── user.ts # 用户相关枚举
│ │ └── index.ts
│ │
│ ├── App.vue # 根组件
│ ├── main.ts # 应用入口
│ └── env.d.ts # 环境类型声明
│
├── tests/ # 测试文件
│ ├── unit/ # 单元测试
│ │ ├── components/
│ │ ├── composables/
│ │ └── utils/
│ ├── e2e/ # 端到端测试
│ ├── setup.ts # 测试配置
│ └── utils/ # 测试工具
│
├── .eslintrc.cjs # ESLint 配置
├── .prettierrc # Prettier 配置
├── .prettierignore # Prettier 忽略文件
├── .gitignore # Git 忽略文件
├── .env # 环境变量
├── .env.development # 开发环境变量
├── .env.production # 生产环境变量
├── index.html # HTML 模板
├── package.json # 项目依赖
├── pnpm-lock.yaml # 依赖锁定文件(或 yarn.lock)
├── tsconfig.json # TypeScript 配置
├── tsconfig.node.json # Node TypeScript 配置
├── vite.config.ts # Vite 配置
└── README.md # 项目说明
📋 目录说明
1. 复杂组件结构(components/business/)
复杂业务组件采用模块化组织,每个组件包含:
- 主组件文件:
ComponentName.vue- 使用<script setup lang="ts"> - 子组件目录:
components/- 存放组件内部使用的子组件 - 组合式函数:
composables/- 逻辑复杂时抽离业务逻辑 hooks - 样式文件:
styles/index.scss- 样式过长时抽离为单独文件 - 导出文件:
index.ts- 统一导出
逻辑处理方案:
- 简单逻辑:直接在
<script setup>中编写 - 复杂逻辑:抽离到
composables/useComponentName.ts
样式处理方案:
- 简单样式:使用
<style scoped>在组件内 - 复杂样式:抽离到
styles/index.scss
示例:UserCard 组件结构
UserCard/
├── UserCard.vue # 主组件(<script setup lang="ts">)
├── components/ # 子组件
│ ├── UserAvatar.vue # 用户头像
│ ├── UserInfo.vue # 用户信息
│ └── UserActions.vue # 用户操作按钮
├── composables/ # 组件 hooks(逻辑复杂时使用)
│ └── useUserCard.ts # 用户卡片相关逻辑
├── styles/ # 组件样式(样式过长时抽离)
│ └── index.scss # 样式文件
└── index.ts # 导出
2. 业务组件结构(views/)
页面级组件采用相同的模块化结构:
- 主页面文件:
PageName.vue或index.vue- 使用<script setup lang="ts"> - 子组件目录:
components/- 页面内部使用的组件 - 组合式函数:
composables/- 逻辑复杂时抽离页面级业务逻辑 - 样式文件:
styles/index.scss- 样式过长时抽离为单独文件 - 子页面目录:支持嵌套的子页面(如
detail/、edit/)
逻辑处理方案:
- 简单逻辑:直接在
<script setup>中编写 - 复杂逻辑:抽离到
composables/usePageName.ts
样式处理方案:
- 简单样式:使用
<style scoped>在组件内 - 复杂样式:抽离到
styles/index.scss
示例:用户管理页面结构
user/
├── index.vue # 用户列表主页面
├── components/ # 页面级组件
│ ├── UserTable.vue # 用户表格
│ ├── UserSearch.vue # 搜索组件
│ └── UserDialog.vue # 对话框组件
├── composables/ # 页面 hooks
│ └── useUserManagement.ts
├── styles/ # 页面样式
│ └── index.scss
│
├── detail/ # 用户详情子页面
│ ├── UserDetail.vue
│ ├── components/
│ ├── composables/
│ └── styles/
│
└── edit/ # 用户编辑子页面
├── UserEdit.vue
├── components/
├── composables/
└── styles/
3. 组合式函数(composables/)
全局可复用的业务逻辑 hooks:
- 通用 hooks:
useAuth.ts、useTable.ts、useForm.ts等 - 工具类 hooks:
useDebounce.ts、useThrottle.ts、useLocalStorage.ts等 - 组件级 hooks:放在对应组件的
composables/目录下
示例:useTable.ts
// composables/useTable.ts
export function useTable<T = any>(api: Function) {
const loading = ref(false)
const tableData = ref<T[]>([])
const pagination = reactive({
current: 1,
pageSize: 10,
total: 0
})
// ... 表格相关逻辑
return {
loading,
tableData,
pagination,
// ... 其他方法
}
}
4. 样式抽离(styles/)
样式采用分层管理,遵循"样式过长时抽离"的原则:
- 全局样式:
src/assets/styles/- 变量、混入、重置样式 - 组件样式:
components/*/styles/- 组件样式过长时抽离 - 页面样式:
views/*/styles/- 页面样式过长时抽离
样式组织原则:
- 简单样式:使用
<style scoped lang="scss">在组件/页面内 - 复杂样式:当样式代码超过 100-150 行时,抽离到独立的
styles/index.scss文件 - 全局样式:统一在
assets/styles/管理
样式文件结构:
assets/styles/
├── variables.scss # SCSS 变量(颜色、尺寸等)
├── mixins.scss # SCSS 混入(复用样式片段)
├── reset.scss # 样式重置
└── index.scss # 样式入口(导入所有全局样式)
components/UserCard/styles/
└── index.scss # UserCard 组件样式(样式过长时抽离)
views/user/styles/
└── index.scss # 用户管理页面样式(样式过长时抽离)
🔧 技术栈说明
- Vue 3:使用 Composition API
- TypeScript:类型安全
- Pinia:状态管理
- Element Plus:UI 组件库
- Vite:构建工具
- ESLint:代码检查
- Prettier:代码格式化
📝 命名规范
- 组件命名:PascalCase(如
UserCard.vue) - 文件命名:
- Vue 组件:PascalCase
- TypeScript 文件:camelCase
- 工具函数:camelCase
- 目录命名:kebabCase(如
userManagement/) - 变量命名:camelCase
- 常量命名:UPPER_SNAKE_CASE
🎯 最佳实践
- 组件拆分:复杂组件拆分为多个子组件
- 逻辑抽离:业务逻辑抽离到 composables
- 样式隔离:每个组件/页面有独立的样式文件
- 类型定义:所有接口和数据结构都有类型定义
- 统一导出:使用
index.ts统一导出,方便引用
✅ 符合业内规范的部分
1. 核心目录结构 ✅
- ✅
src/作为源代码根目录 - ✅
components/和views/分离(组件库 vs 页面) - ✅
composables/用于组合式函数(Vue3 标准做法) - ✅
stores/使用modules/模块化组织(Pinia 推荐) - ✅
router/使用modules/模块化组织 - ✅
api/使用modules/按业务模块划分 - ✅
types/独立目录管理类型定义 - ✅
utils/工具函数集中管理
2. 组件组织方式 ✅
- ✅
components/common/通用基础组件 - ✅
components/business/业务组件 - ✅
components/layout/布局组件 - ✅ 组件内部包含子组件、composables、样式(模块化组织)
3. 页面组织方式 ✅
- ✅
views/按业务模块组织 - ✅ 支持嵌套子页面(detail、edit 等)
- ✅ 页面级组件、hooks、样式分离
4. 样式管理 ✅
- ✅ 全局样式在
assets/styles/ - ✅ 组件样式独立管理
- ✅ 使用 SCSS 变量和混入
5. 配置文件 ✅
- ✅ ESLint、Prettier 配置
- ✅ TypeScript 配置
- ✅ 环境变量文件
本文来自博客园,作者:一尘子!,转载请注明原文链接:https://www.cnblogs.com/mengqc1995/p/19308046

浙公网安备 33010602011771号