Files
huangguo_h5/.cursor/skills/frontend-project-standards/reference.md
T
2026-09-15 15:25:05 +07:00

149 lines
3.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.
# 参考模板
## 1) Service 方法模板
```ts
import request from '@/utils/request';
export interface QueryListParams {
pageNumber: number;
pageSize: number;
mediaId?: string;
}
export interface QueryListResp {
list: Array<{
id: string;
title: string;
}>;
total: number;
}
export default class ExampleApi {
static queryList(params: QueryListParams): Promise<QueryListResp> {
return request.get('/example/list', params);
}
}
```
## 2) Hook 模板(单一职责)
```ts
import { reactive } from 'vue';
import ExampleApi, { QueryListParams } from '@/service/example';
export function useExampleList(initialParams: QueryListParams) {
const state = reactive({
loading: false,
error: false,
list: [] as Array<{ id: string; title: string }>,
total: 0,
});
const fetchList = async (params = initialParams) => {
state.loading = true;
state.error = false;
try {
const res = await ExampleApi.queryList(params);
state.list = res.list || [];
state.total = Number(res.total || 0);
} catch (err) {
state.error = true;
state.list = [];
state.total = 0;
} finally {
state.loading = false;
}
};
return {
state,
fetchList,
};
}
```
## 3) 容器页模板(Container View
```vue
<script setup lang="ts">
import { computed } from 'vue';
import { useRoute } from 'vue-router';
import { useExampleList } from './hooks/useExampleList';
const route = useRoute();
const mediaId = computed(() => String(route.query.id || ''));
const { state, fetchList } = useExampleList({
pageNumber: 1,
pageSize: 30,
mediaId: mediaId.value,
});
fetchList();
</script>
```
## 4) 错误处理最低检查项
- 每个异步动作都具备成对的 loading 开关。
- 请求失败时会落到确定性兜底状态。
- 接口细节与类型由 service 层承载。
- UI 层能展示空态/错误态,不允许静默失败。
## 5) 旧代码 any 的渐进迁移模式
```ts
// 改造前
// static getMediaHot(data: any) {
// return request.get('/media/hot', data);
// }
// 改造后(增量迁移)
export interface GetMediaHotParams {
pageNumber: number;
pageSize: number;
moduleId?: string;
}
export interface GetMediaHotResp {
list: Types.Acg.MediaContentListItem[];
total: number;
}
static getMediaHot(data: GetMediaHotParams): Promise<GetMediaHotResp> {
return request.get('/media/hot', data);
}
```
## 6) PR 自检输出模板
在实现说明中必须附上以下区块(与 `SKILL.md` 保持一致):
```markdown
### 自检结果
- [x] view/hook 层没有直接请求调用
- [x] service 边界方法具备明确类型
- [x] 未新增宽泛 any
- [x] 异步失败分支具备兜底状态
- [x] 混杂职责已拆分为聚焦 hooks/components
```
## 7) 轻量自动校验命令(可执行)
在仓库根目录执行以下命令进行快速自检:
```bash
# 1) 优先检查本次改动的 view/hook 文件是否直接调用 request
rg "request\\.(get|post|put|delete|deletes)\\(" <changed-view-or-hook-files>
# 2) 检查本次改动文件是否引入 any(人工结合 diff 判断)
rg "\\bany\\b" <changed-files>
```
判定规则:
- 命令 1 预期为“无结果”;有结果则说明可能绕过 service。
- 命令 2 不要求仓库清零,但本次改动不应新增宽泛 `any`
- 只有在做全仓治理或用户明确要求时,才扩展到 `src/views src/hooks src/service` 全量扫描。