# Cursor Rules - Web 前端开发规范 ## 适用范围 - **项目目录**: `web/` (基于 Vue 3 + TypeScript + Element Plus) - **开发环境**: Node.js 20.15.x+, npm 10.7.x+ - **前端访问**: http://localhost (默认 80 端口) --- # Web 前端开发规范 (web/) ## 1. 技术栈规范 ### 核心技术 - **框架**: Vue 3.5.13 + TypeScript 5.8.3 - **UI 组件库**: Element Plus 2.9.8 - **构建工具**: Vite 6.3.2 - **状态管理**: Pinia 3.0.2 - **路由管理**: Vue Router 4.5.0 - **HTTP 客户端**: Axios 1.8.4 - **代码风格**: ESLint 9.21.0 + Prettier 3.5.2 - **样式预处理**: SCSS (Sass 1.87.0) - **原子化 CSS**: UnoCSS 66.0.0 - **Node.js**: 20.15.x+ (推荐 20.15.0) - **npm**: 10.7.x+ ### 环境要求 - **开发环境**: 支持本地环境或阿里云测试环境 - **数据库**: MySQL/Redis 支持本机安装或使用阿里云环境 - **前端访问**: http://localhost (默认 80 端口) - **后端服务**: http://localhost:8080 ## 2. Art Design Pro UI 规范 ### 设计理念 基于 Art Design Pro 的设计语言,追求现代化、精致、用户友好的界面体验。注重细节、动效和用户交互的流畅性。 ### 颜色系统 🎨 #### 主色调 (Primary Colors) - 2025 年最新版本 ```css /* 亮色主题 */ :root { --art-primary: 93, 135, 255; /* 主品牌色 - 亮蓝色 #5d87ff */ --art-secondary: 73, 190, 255; /* 辅助色 - 天蓝色 #49beff */ --art-success: 0, 167, 58; /* 成功色 - 绿色 #00a73a */ --art-warning: 142, 91, 0; /* 警告色 - 橙色 #8e5b00 */ --art-error: 250, 137, 107; /* 错误色 - 红色 #fa896b */ --art-info: 0, 75, 178; /* 信息色 - 蓝色 #004bb2 */ --art-danger: 255, 77, 79; /* 危险色 - 红色 #ff4d4f */ } /* 暗色主题 */ html.dark { --art-primary: 93, 135, 255; /* 主品牌色 - 亮蓝色 #5d87ff */ --art-secondary: 73, 190, 255; /* 辅助色 - 天蓝色 #49beff */ --art-success: 19, 222, 185; /* 成功色 - 绿色 #13deb9 */ --art-warning: 255, 174, 31; /* 警告色 - 橙色 #ffae1f */ --art-error: 250, 137, 107; /* 错误色 - 红色 #fa896b */ --art-info: 83, 155, 255; /* 信息色 - 蓝色 #539bff */ --art-danger: 255, 77, 79; /* 危险色 - 红色 #ff4d4f */ } ``` #### 背景色系统 ```css /* 浅色主题 */ :root { --art-bg-color: #fafbfc; /* 页面底色 */ --art-main-bg-color: #ffffff; /* 主要内容背景 */ --art-bg-primary: 236, 242, 255; /* 主色背景 */ --art-bg-secondary: 232, 247, 255; /* 辅助背景 */ --art-bg-success: 230, 255, 250; /* 成功背景 */ --art-bg-warning: 254, 245, 229; /* 警告背景 */ --art-bg-error: 253, 237, 232; /* 错误背景 */ } /* 暗色主题 */ html.dark { --art-bg-color: #070707; /* 页面底色 */ --art-main-bg-color: #161618; /* 主要内容背景 */ } ``` #### 灰色系统 ```css :root { --art-gray-100: #f9f9f9; /* 浅灰 */ --art-gray-200: #f1f1f4; /* 较浅灰 */ --art-gray-300: #dbdfe9; /* 中浅灰 */ --art-gray-400: #c4cada; /* 中灰 */ --art-gray-500: #99a1b7; /* 中深灰 */ --art-gray-600: #78829d; /* 深灰 */ --art-gray-700: #4b5675; /* 较深灰 */ --art-gray-800: #252f4a; /* 很深灰 */ --art-gray-900: #071437; /* 最深灰 */ } ``` ### 轮廓式按钮设计系统 🔘 #### 🎨 设计理念 全面采用轮廓式(Outline)按钮设计,提供更加优雅、现代和一致的用户界面体验。 #### 核心规范 - **Primary 按钮**: 轮廓式主色设计,主色边框和文字,5%透明度主色背景 - **Success 按钮**: 轮廓式成功色设计,成功色边框和文字,5%透明度成功色背景 - **Warning 按钮**: 轮廓式警告色设计,警告色边框和文字,5%透明度警告色背景 - **Danger 按钮**: 轮廓式危险色设计,危险色边框和文字,5%透明度危险色背景 - **Info 按钮**: 轮廓式信息色设计,信息色边框和文字,5%透明度信息色背景 - **Default 按钮**: 白色背景,灰色边框,灰色文字 #### 交互效果 - **悬浮状态**: 上移 1px + 背景透明度变为 10% + 边框透明度变为 80% + 彩色阴影 - **点击状态**: 98%缩放 + 0.1s 快速过渡 + 背景透明度变为 15% - **禁用状态**: 50%透明度,禁用所有交互和变换 ### 🔘 列表页面按钮使用规范(2025 年最新标准) #### 工具栏按钮规范 ```vue ``` #### 操作列按钮规范 ```vue ``` #### 按钮使用规范总结 | 位置 | 按钮类型 | 样式规范 | 示例 | | -------------------- | ---------------- | ---------------------- | -------------------------------------------------------------- | | 工具栏第一个新增按钮 | 新增 | `type="primary" plain` | `新增` | | 工具栏其他按钮 | 修改/删除/导出等 | 无 type(默认) | `修改` | | 表格操作列 | 所有操作按钮 | `link type="primary"` | `` | | 弹窗底部 | 确认按钮 | `type="primary"` | `确定` | | 弹窗底部 | 取消按钮 | 无 type(默认) | `取消` | ### 圆角系统 ```css :root { --border-radius-xs: 4px; /* 超小元素 (checkbox等) */ --border-radius-sm: 6px; /* 小元素 (下拉选项、关闭按钮等) */ --border-radius-md: 8px; /* 表单控件 (input、select、button等) */ --border-radius-lg: 12px; /* 容器组件 (card、table、dialog等) */ --border-radius-xl: 12px; --border-radius-2xl: 16px; --border-radius-full: 50%; } ``` ### 间距系统 ```css :root { --space-xs: 4px; --space-sm: 8px; --space-md: 12px; --space-lg: 16px; --space-xl: 20px; --space-2xl: 24px; --space-3xl: 32px; --space-4xl: 48px; --space-5xl: 64px; } ``` ## 3. 组件开发规范 ### Vue 组件结构标准 ```vue ``` ### 页面开发规范 #### 列表页面标准模板 ```vue ``` #### 表单页面标准模板 ```vue ``` ## 4. API 开发规范 ### API 接口定义标准 ```typescript // api/[module]/index.ts import request from '@/utils/request'; import type { AxiosPromise } from 'axios'; import type { DataVO, DataForm, DataQuery } from './types'; /** * 查询数据列表 * @param query 查询参数 */ export const listData = (query?: DataQuery): AxiosPromise => { return request({ url: '/api/data/list', method: 'get', params: query, }); }; /** * 查询数据详情 * @param id 数据ID */ export const getData = (id: string | number): AxiosPromise => { return request({ url: `/api/data/${id}`, method: 'get', }); }; /** * 新增数据 * @param data 数据信息 */ export const addData = (data: DataForm): AxiosPromise => { return request({ url: '/api/data', method: 'post', data: data, }); }; /** * 修改数据 * @param data 数据信息 */ export const updateData = (data: DataForm): AxiosPromise => { return request({ url: '/api/data', method: 'put', data: data, }); }; /** * 删除数据 * @param ids 数据ID数组 */ export const delData = (ids: Array): AxiosPromise => { return request({ url: `/api/data/${ids}`, method: 'delete', }); }; ``` ### TypeScript 类型定义 ```typescript // api/[module]/types.ts // 查询参数 export interface DataQuery extends PageQuery { name?: string; status?: string; createTime?: [DateModelType, DateModelType]; } // 数据表单 export interface DataForm { id?: string | number; name: string; status: string; remark?: string; } // 数据视图对象 export interface DataVO { id: string | number; name: string; status: string; createTime: string; updateTime: string; remark?: string; } ``` ## 5. 状态管理规范 ### Pinia Store 结构 ```typescript // stores/modules/[module].ts import { defineStore } from 'pinia'; import { ref, computed } from 'vue'; import type { DataVO, DataQuery } from '@/api/[module]/types'; import { listData, getData } from '@/api/[module]'; export const useDataStore = defineStore('[module]', () => { // 状态 const dataList = ref([]); const loading = ref(false); const total = ref(0); // 计算属性 const hasData = computed(() => dataList.value.length > 0); // 方法 const getList = async (query: DataQuery) => { loading.value = true; try { const { data } = await listData(query); dataList.value = data.rows; total.value = data.total; } finally { loading.value = false; } }; const getInfo = async (id: string | number) => { const { data } = await getData(id); return data; }; const reset = () => { dataList.value = []; total.value = 0; }; return { // 状态 dataList, loading, total, // 计算属性 hasData, // 方法 getList, getInfo, reset, }; }); ``` ## 6. 路由管理规范 ### 路由定义标准 ```typescript // router/modules/[module].ts import type { RouteRecordRaw } from 'vue-router'; import Layout from '@/layout/index.vue'; const moduleRouter: RouteRecordRaw = { path: '/[module]', component: Layout, redirect: '/[module]/list', name: 'Module', meta: { title: '模块管理', icon: 'example', alwaysShow: true, }, children: [ { path: 'list', component: () => import('@/views/[module]/index.vue'), name: 'ModuleList', meta: { title: '列表管理', activeMenu: '/[module]/list', }, }, { path: 'add', component: () => import('@/views/[module]/form.vue'), name: 'ModuleAdd', meta: { title: '新增数据', activeMenu: '/[module]/list', }, hidden: true, }, { path: 'edit/:id(\\d+)', component: () => import('@/views/[module]/form.vue'), name: 'ModuleEdit', meta: { title: '编辑数据', activeMenu: '/[module]/list', }, hidden: true, }, ], }; export default moduleRouter; ``` ## 7. 项目架构规范 ### 目录结构 ``` web/src/ ├── api/ # API接口定义 │ ├── [module]/ │ │ ├── index.ts # 接口方法 │ │ └── types.ts # 类型定义 ├── assets/ # 静态资源 │ ├── images/ # 图片资源 │ └── styles/ # 样式文件 │ ├── art-variables.scss # Art Design Pro 变量 │ ├── art-element-ui.scss # Element Plus 样式定制 │ ├── art-global.scss # 全局样式 │ ├── art-dark.scss # 暗色主题 │ └── index.scss # 样式入口 ├── components/ # 全局组件 ├── hooks/ # 组合式函数 ├── layout/ # 布局组件 ├── plugins/ # 插件配置 ├── router/ # 路由配置 ├── stores/ # 状态管理 ├── types/ # 全局类型定义 ├── utils/ # 工具函数 ├── views/ # 页面组件 └── main.ts # 应用入口 ``` ### 文件命名规范 - **组件文件**: PascalCase,如 `UserForm.vue` - **页面文件**: kebab-case,如 `user-list.vue` - **工具文件**: camelCase,如 `formatUtils.ts` - **类型文件**: PascalCase,如 `UserTypes.ts` ## 8. 样式开发规范 ### SCSS 变量使用 ```scss // 使用 Art Design Pro 变量系统 .custom-component { background-color: var(--art-main-bg-color); border: 1px solid var(--art-border-color); border-radius: var(--border-radius-lg); padding: var(--space-lg); .title { color: var(--art-text-gray-900); font-size: 16px; font-weight: 500; } .content { color: var(--art-text-gray-700); margin-top: var(--space-md); } } ``` ### UnoCSS 工具类 ```vue ``` ## 9. 性能优化规范 ### 组件懒加载 ```typescript // 路由级别的懒加载 const UserList = () => import('@/views/user/index.vue'); // 组件级别的懒加载 const AsyncComponent = defineAsyncComponent(() => import('@/components/HeavyComponent.vue')); ``` ### 图片优化 ```vue ``` ## 10. 开发最佳实践 ### 代码规范 1. **组件命名**: 使用 PascalCase 2. **方法命名**: 使用 camelCase,语义化命名 3. **常量命名**: 使用 UPPER_SNAKE_CASE 4. **注释规范**: 使用 JSDoc 格式 ### 错误处理 ```typescript // API错误处理 const handleSubmit = async () => { try { loading.value = true; await submitData(formData); ElMessage.success('操作成功'); } catch (error) { console.error('提交失败:', error); ElMessage.error('操作失败'); } finally { loading.value = false; } }; ``` ### 类型安全 ```typescript // 严格的类型定义 interface UserForm { name: string; email: string; status: 0 | 1; } // 类型断言 const user = data as UserForm; ``` ## 11. 测试规范 ### 单元测试 ```typescript // 使用 Vitest 进行单元测试 import { describe, it, expect } from 'vitest'; import { mount } from '@vue/test-utils'; import UserForm from '@/components/UserForm.vue'; describe('UserForm', () => { it('should render correctly', () => { const wrapper = mount(UserForm); expect(wrapper.exists()).toBe(true); }); }); ``` ## 12. 构建与部署 ### 环境配置 ```typescript // .env.development VITE_APP_BASE_API = '/dev-api'; VITE_APP_PORT = 80; // .env.production VITE_APP_BASE_API = '/prod-api'; VITE_APP_PORT = 80; ``` ### 构建优化 ```typescript // vite.config.ts export default defineConfig({ build: { rollupOptions: { output: { chunkFileNames: 'js/[name]-[hash].js', entryFileNames: 'js/[name]-[hash].js', assetFileNames: '[ext]/[name]-[hash].[ext]', }, }, }, }); ``` --- ## 总结 本规范文档涵盖了杭州第一技师学院智慧校园管理系统前端开发的所有核心规范,包括最新的品牌色配置和统一的按钮使用规范。开发者应严格遵循这些规范,确保代码质量和用户体验的一致性。 **🔴 重要提醒**: 1. **按钮规范**: 工具栏第一个新增按钮必须使用 `type="primary" plain`,其他按钮使用默认样式 2. **颜色系统**: 使用最新的 Art Design Pro 颜色变量 3. **文档同步**: 代码变更后必须同步更新相关文档