Files
djangoadmin-wiki/DjangoAdmin_FastAPI_NaiveVue/zh/volume4/frontend/setup.md
T
2026-09-14 10:33:29 +08:00

215 lines
7.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 前端环境与结构
:::tip 说明
前端基于 Vue3 + NaiveUI 构建,使用 pnpm 作为包管理工具,Vite 作为构建工具,TypeScript 作为开发语言。
:::
## 技术栈
| 技术 | 版本 | 说明 |
|------|------|------|
| Vue | 3.x | 渐进式 JavaScript 框架,组合式 API |
| NaiveUI | 2.x | Vue3 组件库 |
| Vite | 3.x | 下一代前端构建工具 |
| Pinia | 2.x | 状态管理(Vuex 替代方案) |
| Vue Router | 4.x | 路由管理 |
| Axios | 1.x | HTTP 请求库 |
| TypeScript | 5.x | 类型安全的 JavaScript 超集 |
| Tailwind CSS | 3.x | 原子化 CSS 框架 |
| Less | - | CSS 预处理器 |
## 目录结构
```
ui/
├── src/
│ ├── api/ # API 接口定义
│ │ ├── common/ # 公共接口(login、menu、user)
│ │ └── system/ # 系统模块接口(position、user、role 等)
│ ├── assets/ # 静态资源(图片、字体等)
│ ├── components/ # 公共组件(Table、Form、Modal 等)
│ ├── directives/ # 自定义指令(v-perm 权限指令)
│ ├── hooks/ # 组合式函数
│ │ ├── event/ # 事件相关(useWindowSizeFn、useBreakpoint)
│ │ ├── setting/ # 配置相关(useProjectSetting、useDesignSetting)
│ │ └── web/ # Web 相关(usePermission、useECharts)
│ ├── layout/ # 布局组件
│ ├── router/ # 路由配置(generator-routers、router-guards)
│ ├── store/ # Pinia 状态管理
│ │ └── modules/ # Store 模块(user、asyncRoute、projectSetting 等)
│ ├── styles/ # 全局样式(Less 变量、Tailwind)
│ ├── utils/ # 工具函数(http、auth、Storage、dateUtil)
│ │ └── http/axios/ # Axios 封装(VAxios 类、拦截器、取消请求)
│ └── views/ # 页面视图
│ └── system/ # 系统管理页面(position、user、role 等)
├── build/ # 构建配置(vite 插件、常量、工具函数)
├── public/ # 公共静态资源
├── vite.config.ts # Vite 配置
├── tsconfig.json # TypeScript 配置
└── package.json # 依赖配置
```
## 启动开发
```bash
# 安装依赖
pnpm install
# 启动开发服务器(默认端口 8001)
pnpm dev
# 构建生产版本
pnpm build
```
## Vite 配置
`vite.config.ts` 是 Vite 的核心配置文件,实际配置如下:
```typescript
import type { UserConfig, ConfigEnv } from 'vite';
import { loadEnv } from 'vite';
import { resolve } from 'path';
import { wrapperEnv } from './build/utils';
import { createVitePlugins } from './build/vite/plugin';
import { OUTPUT_DIR } from './build/constant';
import { createProxy } from './build/vite/proxy';
export default ({ command, mode }: ConfigEnv): UserConfig => {
const root = process.cwd();
const env = loadEnv(mode, root);
const viteEnv = wrapperEnv(env);
const { VITE_PUBLIC_PATH, VITE_PORT, VITE_GLOB_PROD_MOCK } = viteEnv;
let VITE_PROXY: any = viteEnv.VITE_PROXY;
// VITE_PROXY 容错处理
if (!VITE_PROXY) {
VITE_PROXY = '[[]]';
}
try {
if (typeof VITE_PROXY === 'string') {
VITE_PROXY = JSON.parse(VITE_PROXY);
}
} catch (e) {
VITE_PROXY = [[]];
}
const isBuild = command === 'build';
return {
base: VITE_PUBLIC_PATH,
resolve: {
alias: [
{ find: '@', replacement: pathResolve('src') + '/' },
],
dedupe: ['vue'],
},
plugins: createVitePlugins(viteEnv, isBuild, prodMock),
css: {
preprocessorOptions: {
less: {
additionalData: `@import "src/styles/var.less";`,
},
},
},
server: {
host: true,
port: VITE_PORT,
proxy: createProxy(VITE_PROXY),
},
build: {
target: 'es2015',
outDir: OUTPUT_DIR,
reportCompressedSize: false,
chunkSizeWarningLimit: 2000,
},
};
};
```
关键配置说明:
- `@` 别名指向 `src/` 目录,代码中可用 `@/api/system/position` 引入模块
- Less 全局变量通过 `additionalData` 注入,无需每个文件手动 `@import`
- 代理配置通过 `VITE_PROXY` 环境变量传入,由 `createProxy()` 工具函数解析
- 构建产物输出到 `OUTPUT_DIR`(默认 `dist/`)
## 应用入口
`src/main.ts` 是应用入口,负责初始化所有基础设施:
```typescript
import './styles/tailwind.css';
import './styles/index.less';
import { createApp } from 'vue';
import App from './App.vue';
import router, { setupRouter } from './router';
import { setupStore } from '@/store';
import {
setupNaive,
setupDirectives,
setupCustomComponents,
setupNaiveDiscreteApi,
} from '@/plugins';
async function bootstrap() {
const app = createApp(App);
setupStore(app); // 挂载 Pinia 状态管理
setupNaive(app); // 全局注册 NaiveUI 组件
setupCustomComponents(app); // 注册自定义组件
setupNaiveDiscreteApi(); // 挂载 NaiveUI 脱离上下文的 Api
await setupDirectives(app); // 注册自定义指令(v-perm 等)
await setupRouter(app); // 挂载路由
await router.isReady(); // 路由准备就绪
app.mount('#app', true);
}
void bootstrap();
```
初始化顺序:Pinia Store -> NaiveUI -> 自定义组件 -> NaiveUI DiscreteApi -> 自定义指令 -> Router -> 挂载。
## 核心目录说明
### api/
API 接口定义目录,按模块组织文件。公共接口在 `api/common/`(login、menu、user),业务接口在 `api/system/`(position、user、role、dept、level、menu、dictionary 等)。每个文件使用 `http.request()` 发起请求。
### components/
公共组件目录,基于 NaiveUI 二次封装,包含 `Table`(BasicTable 表格)、`Form`(BasicForm 表单)、`Modal`(BasicModal 弹窗)、`Upload`、`Editor`、`Cropper`、`Select` 等。
### directives/
自定义指令目录,核心是 `permission.ts` 中的 `v-perm` 和 `v-perms` 指令,用于按钮级别的权限控制。
### hooks/
组合式函数目录,包括 `usePermission`(权限检查)、`useTime`(实时时钟)、`useAsync`(异步 loading)、`useProjectSetting`(项目配置)、`useDesignSetting`(设计配置)等。
### store/
Pinia 状态管理目录,核心模块:
- `user`:用户登录状态、Token、用户信息、权限列表
- `asyncRoute`:动态路由生成、菜单管理、组件缓存
- `projectSetting`:项目配置(权限模式、水印等)
- `designSetting`:主题色、深色模式
- `lockscreen`:锁屏状态
- `tabsView`:标签页管理
### utils/
工具函数目录:
- `http/axios/`:Axios 封装(VAxios 类、请求/响应拦截器、取消重复请求、状态码处理)
- `auth.ts`:认证工具(token 管理、树结构操作、文件下载)
- `Storage.ts`:本地存储封装(支持过期时间、cookie)
- `dateUtil.ts`:日期格式化(基于 dayjs)
## 总结
前端项目基于 Vue3 + NaiveUI + Vite + TypeScript + Pinia 构建,使用 pnpm 管理依赖,Tailwind CSS + Less 提供样式能力。通过 `main.ts` 的 `bootstrap()` 函数按顺序初始化所有基础设施,目录结构按功能分层组织,便于维护和扩展。