Skip to content

开发指南

开发环境搭建

系统要求

  • 操作系统: 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')
  }
})

调试技巧

浏览器调试

  1. Vue DevTools: 安装浏览器扩展,查看组件树和状态
  2. Network: 查看 API 请求和响应
  3. 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

性能优化

前端优化

  1. 路由懒加载: 页面组件按需加载
  2. 组件按需引入: Ant Design Vue 组件按需导入
  3. 图片优化: 使用合适的图片格式和尺寸
  4. 状态持久化: Pinia 状态自动持久化到 localStorage

构建优化

  1. 代码分割: Vite 自动代码分割
  2. 压缩配置: Terser 压缩 JS,压缩插件压缩资源
  3. Gzip 压缩: vite-plugin-compression 开启 Gzip

部署

静态部署

bash
# 构建
npm run build

# 部署 dist 目录到静态服务器

Docker 部署

bash
# 构建镜像
docker build -t airadmin:latest .

# 运行容器
docker run -d -p 80:80 airadmin:latest

Nginx 配置

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 变量。

相关资源