介绍
本文是 Vue3 + Vite + TypeScript + Element Plus + Axios + Pinia 企业级标准目录结构。
结构完全可直接落地,每个目录都配典型文件示例,照着建就能直接开发。
完整项目目录
your-project/
├── public/ # 静态资源(不参与构建)
│ └── favicon.ico
├── src/
│ ├── api/ # 所有接口请求
│ │ ├── modules/ # 按业务拆分接口
│ │ │ ├── user.ts # 用户接口(登录/获取信息)
│ │ │ └── system.ts # 系统/菜单/权限接口
│ │ └── request.ts # axios 封装(拦截器/统一错误)
│ ├── assets/ # 需构建的资源
│ │ ├── images/
│ │ └── styles/
│ │ ├── global.scss # 全局样式
│ │ └── variables.scss# 主题变量
│ ├── components/ # 全局公共组件
│ │ ├── base/ # 基础组件
│ │ │ └── SvgIcon.vue
│ │ └── business/ # 业务通用组件
│ │ └── UserSelect.vue
│ ├── composables/ # Vue3 组合式函数
│ │ ├── useUser.ts
│ │ └── useTable.ts
│ ├── config/ # 全局配置
│ │ └── index.ts
│ ├── directives/ # 自定义指令
│ │ ├── permission.ts
│ │ └── index.ts
│ ├── layouts/ # 页面布局
│ │ ├── MainLayout.vue
│ │ └── BlankLayout.vue
│ ├── router/ # 路由
│ │ ├── modules/ # 路由模块
│ │ │ ├── user.ts
│ │ │ └── system.ts
│ │ ├── guard.ts # 路由守卫
│ │ └── index.ts
│ ├── store/ # Pinia 状态
│ │ ├── modules/
│ │ │ ├── user.ts
│ │ │ └── app.ts
│ │ └── index.ts
│ ├── types/ # TS 类型定义
│ │ ├── user.ts
│ │ └── common.ts
│ ├── utils/ # 工具函数
│ │ ├── storage.ts
│ │ └── format.ts
│ ├── views/ # 页面
│ │ ├── user/
│ │ │ ├── login.vue
│ │ │ └── profile.vue
│ │ ├── system/
│ │ │ ├── userList.vue
│ │ │ └── menuList.vue
│ │ └── dashboard/
│ │ └── index.vue
│ ├── App.vue
│ ├── main.ts
│ └── env.d.ts # TS 环境声明
├── .env # 开发环境
├── .env.production # 生产环境
├── vite.config.ts
├── tsconfig.json
└── package.json
详细说明
1)public/
作用:不经过 Vite 构建,直接复制到 dist
典型文件:
- favicon.ico
- robots.txt
2)src/api/ —— 接口请求(最常用)
api/request.ts(axios 封装)
import axios from 'axios'
const service = axios.create({ baseURL: import.meta.env.VITE_API_URL })
// 请求拦截:加 token
// 响应拦截:统一错误、401 跳转登录
export default service
api/modules/user.ts
import request from '../request'
export const login = (data: any) => request.post('/user/login', data)
export const getUserInfo = () => request.get('/user/info')
api/modules/system.ts
import request from '../request'
export const getMenuList = () => request.get('/system/menu')
export const getRoleList = () => request.get('/system/role')
3)src/assets/ —— 资源文件
- images/:图片
- styles/global.scss:全局样式
- styles/variables.scss:主题色、变量
4)src/components/ —— 全局组件
base/SvgIcon.vue
全局 SVG 图标组件
business/UserSelect.vue
用户选择器(多个页面使用)
5)src/composables/ —— Vue3 逻辑复用
useUser.ts
import { useUserStore } from '@/store/modules/user'
export function useUser() {
const userStore = useUserStore()
const getUserInfo = async () => await userStore.getInfo()
return { user: userStore.user, getUserInfo }
}
useTable.ts
表格分页、查询、重置通用逻辑
6)src/config/index.ts
全局常量、项目标题、默认配置
export const SITE_TITLE = '企业管理系统'
export const TOKEN_KEY = 'TOKEN'
7)src/directives/ —— 自定义指令
permission.ts
按钮权限指令 v-permission
index.ts
统一注册所有指令
8)src/layouts/ —— 布局
MainLayout.vue
后台布局:侧边栏 + 顶部 + 内容区
BlankLayout.vue
空白布局(登录、404)
9)src/router/ —— 路由
guard.ts
路由守卫:判断是否登录、是否有权限
modules/user.ts
export default {
path: '/user',
component: MainLayout,
children: [
{ path: 'login', component: () => import('@/views/user/login.vue') }
]
}
10)src/store/ —— Pinia 状态
modules/user.ts
import { defineStore } from 'pinia'
export const useUserStore = defineStore('user', {
state: () => ({ token: '', userInfo: {} }),
actions: {
async login(data) { /* 登录逻辑 */ },
async getInfo() { /* 获取信息 */ }
}
})
modules/app.ts
控制侧边栏、主题、全局 loading
11)src/types/ —— TS 类型
user.ts
export interface UserInfo {
id: number
name: string
avatar: string
}
common.ts
export interface PageResult<T> {
list: T[]
total: number
}
12)src/utils/ —— 工具
storage.ts
本地存储封装
format.ts
时间格式化、金额格式化
13)src/views/ —— 页面
user/login.vue
登录页(Element Plus 表单)
system/userList.vue
用户列表页(表格 + 搜索 + 分页)
dashboard/index.vue
首页
14)src/main.ts —— 入口
import { createApp } from 'vue'
import App from './App.vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import { createPinia } from 'pinia'
import router from './router'
import './assets/styles/global.scss'
const app = createApp(App)
app.use(createPinia())
app.use(router)
app.use(ElementPlus)
app.mount('#app')
企业开发规范
- 接口统一放 api/modules
- 全局状态放 store
- 公共逻辑抽 composables
- 页面只做组合,不写复杂逻辑
- TS 类型统一放 types
- 路由、store、api 都按业务模块拆分