test-frontend/.claude/frontend.md

200 lines
5.8 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.

# 03 — 前端规则
> **适用**:所有前端 AI 开发任务Web / H5 / 小程序)。
---
## 样式铁律
**禁止在组件文件中硬编码**:颜色值(`#xxx` / `rgb()`)、字号(`px` / `rpx` / `rem`)、间距(`margin` / `padding` 数值)、圆角(`border-radius` 数值)。
所有样式必须来自:
1. **Design Token 文件** → 变量(`$color-primary`
2. **全局 CSS 类** → 语义类(`.text-h1` `.card` `.gap-2`
3. **UI 框架内置类** → Tailwind / Ant Design 等
```vue
<!-- 禁止 -->
<style scoped>
.title { color: #333; font-size: 32rpx; margin: 20rpx; }
<!-- 正确 -->
<style scoped>
.title { color: $color-gray-800; @extend .text-h2; margin: $space-3; }
```
---
## 命名规则
| 元素 | 规则 | 示例(正确 → 错误) |
|------|------|---------------------|
| **组件文件** | 短横线分隔kebab-case | `task-card.vue` → ❌ `TaskCard.vue` |
| **页面文件** | 小写或短横线 | `task-detail.vue` `index.vue` |
| **组件 name** | 大驼峰PascalCase | `TaskCard` `UserAvatar` |
| **CSS 类名** | 短横线分隔 | `.task-card` `.btn-primary` → ❌ `.taskCard` |
| **JS 变量** | 小驼峰 | `taskList` `userName` → ❌ `task_list` |
| **JS 常量** | 全大写,下划线分隔 | `MAX_PAGE_SIZE` `API_BASE_URL` |
| **JS 函数** | 小驼峰,动词开头 | `fetchTasks()` `handleSubmit()` |
| **API 方法** | 小驼峰,动词+名词 | `taskApi.list()` `taskApi.create()` |
| **路由路径** | 小写,短横线 | `/task-detail` → ❌ `/taskDetail` |
| **文件目录** | 小写或短横线 | `task-hall/` `user-center/` |
| **静态资源** | 短横线分隔 | `icon-phone.svg` `bg-home.jpg` |
---
## 注释规则
| 位置 | 要求 | 示例 |
|------|------|------|
| **组件** | 顶部注释说明用途和 Props | `<!-- 任务卡片组件,用于列表展示 -->` |
| **复杂逻辑** | 行内注释说明"为什么" | `// 先查本地缓存,未命中再请求接口` |
| **计算属性** | 注释说明计算依据 | `// 根据任务状态和截止时间计算紧急程度` |
| **API 方法** | JSDoc 说明入参/返回 | `@param {Object} params @returns {Promise<{list,total}>}` |
| **TODO/FIXME** | 负责人+日期 | `// TODO(yaoshuli 2026-06) 待产品确认逻辑` |
| **禁止** | ❌ 注释写"做了什么" | `<!-- 循环渲染列表 -->` ← 删掉 |
| **禁止** | ❌ 注释掉的旧代码/旧模板 | 直接删Git 有历史 |
| **禁止** | ❌ 无意义分隔注释 | `// ========== 数据获取 ==========` |
```vue
<!--
任务详情页面
- 展示任务基本信息报名列表结算记录
- 支持接单提交结算等操作
-->
<template>
<app-layout>
<!-- 任务信息卡片 -->
<m-card>
...
</m-card>
<!-- 仅管理员可见 -->
<m-card v-if="isAdmin">
...
</m-card>
</app-layout>
</template>
<script setup>
/**
* 提交任务成果。
* 提交成功后自动刷新列表并发送通知。
*
* @param {string} taskId - 任务ID
* @param {Object} payload - 提交内容 { files, remark }
* @returns {Promise<void>}
*/
const handleSubmit = async (taskId, payload) => {
// 先本地校验,避免无效请求
if (!payload.files.length) return;
await taskApi.submit(taskId, payload);
// TODO(yaoshuli 2026-06) 成功后应跳转到提交记录页
router.push('/task-list');
};
</script>
```
---
## 组件使用铁律
| 场景 | ✅ 必须用 | ❌ 禁止 |
|------|----------|---------|
| 页面外壳 | 项目统一布局组件 | 自己写页头/侧栏/底栏/TabBar |
| 图标 | 项目统一图标组件 | 裸 `<img>` / emoji / Unicode |
| 按钮 | 项目统一按钮组件 | 自己写 button 样式 |
| 卡片 | 项目统一卡片组件 | 裸露 div+手写圆角阴影 |
---
## API 调用铁律
**所有 HTTP 请求走统一封装**,禁止组件内直调原生 API。
```javascript
// ✅ 正确:走项目统一封装
import { taskApi } from '@/services/task';
const res = await taskApi.list({ page: 1, size: 20 });
// ❌ 禁止
fetch('/api/task/list').then(...)
axios.get('/api/task/list')
uni.request({ url: '/api/task/list' })
```
---
## 新增页面模板(填空式)
```vue
<template>
<app-layout>
<!-- [填空] 页面内容 -->
<view v-if="loading">加载中...</view>
<view v-else-if="list.length === 0" class="empty-state">
<text>暂无数据</text>
</view>
<view v-else>
<!-- [填空] 数据展示 -->
</view>
</app-layout>
</template>
<script setup>
import { ref, onMounted } from 'vue';
// [填空] import API 方法
const list = ref([]);
const loading = ref(false);
const fetchData = async () => {
loading.value = true;
try {
const res = await [API方法]({ page: 1, size: 20 });
list.value = res.list;
} finally {
loading.value = false;
}
};
onMounted(() => fetchData());
</script>
<style scoped lang="scss">
// ⚠️ 不得超过 100 行,超过说明在造轮子
</style>
```
---
## 禁止清单
| 类别 | ❌ 禁止 |
|------|--------|
| **样式** | 硬编码颜色/字号/间距/圆角 |
| **样式** | 在 scoped 中定义全局重置 |
| **样式** | scoped 超过 100 行 |
| **组件** | 自己写布局外壳(页头/侧栏/TabBar |
| **组件** | 裸用 `<img>` 代替图标组件 |
| **网络** | 直调 `fetch` / `axios` / `uni.request` |
| **网络** | 不处理错误态 |
| **状态** | 无加载态/空态 |
---
## 检查表
每完成一个前端任务,逐项自检:
- [ ] 使用项目统一布局组件
- [ ] 无硬编码颜色/字号/间距/圆角
- [ ] 图标全部走统一图标组件
- [ ] API 调用走统一封装,无裸调
- [ ] 页面/组件有加载态 + 空态 + 错误态
- [ ] 关键操作有 loading 态(防重复点击)
- [ ] `<style scoped>` 不超过 100 行
- [ ] PC/移动端均正常(如项目需响应式)
- [ ] 无禁止清单中的违规项