开发指南
开发环境搭建
系统要求
- 操作系统: macOS / Windows / Linux
- Node.js: >= 18.0.0
- 包管理器: npm >= 9.0.0 或 pnpm >= 8.0.0
- Git: >= 2.30.0
推荐工具
- IDE: VSCode / WebStorm
- 浏览器: Chrome / Edge / Safari(最新版)
- VSCode 插件: Vue - Official、UnoCSS、ESLint
项目架构
技术栈
| 层级 | 技术 |
|---|---|
| 前端框架 | Vue 3 + TypeScript |
| 状态管理 | Pinia |
| 路由 | Vue Router |
| UI 组件 | Ant Design Vue |
| 图标 | @ant-design/icons-vue + @iconify |
| CSS 方案 | UnoCSS |
| 图表 | ECharts |
| 国际化 | Vue I18n |
| 构建工具 | Vite |
目录结构
airadmin/
├── public/ # 静态资源
│ └── logo.svg # 应用 Logo
├── src/ # 源代码
│ ├── components/ # 公共组件
│ │ ├── Icon/ # 图标组件
│ │ └── AirTabsBar.vue # 标签栏组件
│ ├── composables/ # 组合式函数
│ │ └── useECharts.ts # ECharts 组合式函数
│ ├── directives/ # 自定义指令
│ │ ├── index.ts # 指令入口
│ │ ├── v-auth.ts # 权限指令
│ │ ├── v-loading.ts # 加载指令
│ │ └── v-permission.ts # 权限判断指令
│ ├── enums/ # 枚举定义
│ │ └── index.ts # 枚举入口
│ ├── layouts/ # 布局组件
│ │ └── AppLayout.vue # 应用布局
│ ├── router/ # 路由配置
│ │ ├── index.ts # 路由入口
│ │ └── modules/ # 路由模块
│ │ ├── demo.ts # 示例路由
│ │ └── example-nested.ts # 嵌套路由示例
│ ├── utils/ # 工具函数
│ │ ├── clone.ts # 深拷贝
│ │ ├── crypto-storage.ts # 加密存储
│ │ ├── date.ts # 日期工具
│ │ ├── echarts.ts # ECharts 工具
│ │ ├── index.ts # 工具入口
│ │ ├── is.ts # 类型判断
│ │ ├── pinia-persist.ts # 状态持久化
│ │ └── storage.ts # 本地存储
│ ├── views/ # 页面视图
│ │ ├── AnalyticsView.vue # 数据分析
│ │ ├── DashboardView.vue # 仪表盘
│ │ ├── DemoPageView.vue # 示例页面
│ │ ├── ExceptionView.vue # 异常页面
│ │ ├── NotFoundView.vue # 404 页面
│ │ ├── ProfileView.vue # 个人中心
│ │ ├── SettingsView.vue # 系统设置
│ │ └── UsersView.vue # 用户管理
│ ├── App.vue # 根组件
│ ├── env.d.ts # 环境类型声明
│ ├── init.ts # 初始化逻辑
│ └── main.ts # 入口文件
├── index.html # HTML 模板
├── package.json # 项目配置
├── tsconfig.json # TypeScript 配置
├── tsconfig.node.json # Node TypeScript 配置
├── uno.config.ts # UnoCSS 配置
└── vite.config.ts # Vite 配置开发规范
代码规范
- 使用 ESLint + Prettier 进行代码格式化
- 遵循 Vue 3 组合式 API 风格
- TypeScript 严格模式启用
- 组件命名使用 PascalCase
- 函数命名使用 camelCase
- CSS 使用 UnoCSS 原子化类名
Git 规范
类型(scope): 简短描述
详细描述(可选)
Footer(可选)类型说明:
feat: 新功能fix: 修复docs: 文档style: 格式refactor: 重构perf: 性能优化test: 测试chore: 构建/工具
示例:
feat(ai): 添加 AI 命令面板快捷键支持
- 支持 Ctrl+K 呼出命令面板
- 支持自定义快捷键配置
- 添加命令历史记录功能
Closes #123分支管理
main: 主分支,稳定版本develop: 开发分支feature/*: 功能分支hotfix/*: 紧急修复release/*: 发布分支
模块开发
页面开发
vue
<template>
<div class="p-4">
<a-card title="用户管理">
<a-table :columns="columns" :data-source="users" />
</a-card>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue'
const columns = [
{ title: '用户名', dataIndex: 'username' },
{ title: '邮箱', dataIndex: 'email' },
{ title: '状态', dataIndex: 'status' },
]
const users = ref([])
onMounted(async () => {
users.value = await fetchUsers()
})
</script>组合式函数开发
typescript
import { ref, onMounted, onUnmounted } from 'vue'
import * as echarts from 'echarts'
export function useECharts(container: Ref<HTMLElement | null>) {
let chart: echarts.ECharts | null = null
const initChart = () => {
if (container.value) {
chart = echarts.init(container.value)
}
}
const setOption = (option: echarts.EChartsOption) => {
chart?.setOption(option)
}
const resize = () => {
chart?.resize()
}
onMounted(() => {
initChart()
window.addEventListener('resize', resize)
})
onUnmounted(() => {
window.removeEventListener('resize', resize)
chart?.dispose()
})
return { setOption, resize }
}自定义指令开发
typescript
import type { Directive } from 'vue'
export const vAuth: Directive = {
mounted(el, binding) {
const { value } = binding
const userPermissions = getUserPermissions()
if (value && !userPermissions.includes(value)) {
el.parentNode?.removeChild(el)
}
}
}AI 命令注册
typescript
import { registerCommand } from '@gitcoffee/air-engine'
registerCommand({
id: 'open-user-management',
label: '打开用户管理',
icon: 'UserOutlined',
trigger: ['用户管理', '查看用户', '打开用户管理'],
category: 'navigation',
handler: () => {
router.push('/system/users')
}
})调试技巧
浏览器调试
- Vue DevTools: 安装浏览器扩展,查看组件树和状态
- Network: 查看 API 请求和响应
- Console: 查看日志输出
状态调试
typescript
import { useUserStore } from '@/stores/user'
const userStore = useUserStore()
// 在控制台中查看状态
console.log('当前用户:', userStore.userInfo)
console.log('权限列表:', userStore.permissions)测试
单元测试
bash
# 运行所有测试
npm run test
# 运行指定模块测试
npm run test -- src/views
# 覆盖率报告
npm run test:coverage类型检查
bash
# 运行 TypeScript 类型检查
npm run typecheck性能优化
前端优化
- 路由懒加载: 页面组件按需加载
- 组件按需引入: Ant Design Vue 组件按需导入
- 图片优化: 使用合适的图片格式和尺寸
- 状态持久化: Pinia 状态自动持久化到 localStorage
构建优化
- 代码分割: Vite 自动代码分割
- 压缩配置: Terser 压缩 JS,压缩插件压缩资源
- Gzip 压缩: vite-plugin-compression 开启 Gzip
部署
静态部署
bash
# 构建
npm run build
# 部署 dist 目录到静态服务器Docker 部署
bash
# 构建镜像
docker build -t airadmin:latest .
# 运行容器
docker run -d -p 80:80 airadmin:latestNginx 配置
nginx
server {
listen 80;
server_name airadmin.example.com;
root /usr/share/nginx/html;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
location /api {
proxy_pass http://backend:8080;
}
}常见问题
Q: 如何添加新的路由页面?
A: 在 src/views/ 下创建 Vue 组件,然后在 src/router/modules/ 中新建路由模块文件。
Q: 如何使用 AI 命令面板?
A: 按 Ctrl + K(macOS: Cmd + K)呼出命令面板,输入自然语言命令即可。
Q: 如何配置权限控制?
A: 使用 v-auth 指令控制按钮级别权限,使用 v-permission 指令控制元素显示权限。
Q: 如何自定义主题颜色?
A: 修改 uno.config.ts 中的主题配置和 CSS 变量。