2026-06-24 9e873214473df3e43ee53535db9831ecf03e4a0f
添加项目技能
已添加12个文件
1116 ■■■■■ 文件已修改
.claude/add-language-rules.md 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.claude/api-service.md 84 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.claude/database-migration.md 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.claude/feature-development.md 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.claude/pinia-store.md 99 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.claude/settings.local.json 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.claude/skills/antd-vue-components/SKILL.md 212 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.claude/skills/frontend-code-review/SKILL.md 168 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.claude/skills/vue3-development/SKILL.md 155 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.claude/vue-component.md 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.claude/vue-page.md 95 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
CLAUDE.md 94 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.claude/add-language-rules.md
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,39 @@
---
name: add-language-rules
description: Workflow command scaffold for add-language-rules in everything-claude-code.
allowed_tools: ["Bash", "Read", "Write", "Grep", "Glob"]
---
# /add-language-rules
Use this workflow when working on **add-language-rules** in `everything-claude-code`.
## Goal
Adds a new programming language to the rules system, including coding style, hooks, patterns, security, and testing guidelines.
## Common Files
- `rules/*/coding-style.md`
- `rules/*/hooks.md`
- `rules/*/patterns.md`
- `rules/*/security.md`
- `rules/*/testing.md`
## Suggested Sequence
1. Understand the current state and failure mode before editing.
2. Make the smallest coherent change that satisfies the workflow goal.
3. Run the most relevant verification for touched files.
4. Summarize what changed and what still needs review.
## Typical Commit Signals
- Create a new directory under rules/{language}/
- Add coding-style.md, hooks.md, patterns.md, security.md, and testing.md files with language-specific content
- Optionally reference or link to related skills
## Notes
- Treat this as a scaffold, not a hard-coded script.
- Update the command if the workflow evolves materially.
.claude/api-service.md
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,84 @@
---
name: api-service
description: åˆ›å»ºæ–°çš„ API æœåŠ¡æ¨¡å—ï¼ŒåŒ…å« TypeScript ç±»åž‹å®šä¹‰
allowed_tools: ["Bash", "Read", "Write", "Grep", "Glob"]
---
# /api-service
创建新的 API æœåŠ¡æ¨¡å—æ—¶ä½¿ç”¨æ­¤å·¥ä½œæµã€‚
## ç›®æ ‡
创建一个类型安全的 API æœåŠ¡æ¨¡å—ï¼ŒåŒ…å«æ­£ç¡®çš„è¯·æ±‚/响应类型定义。
## å¸¸ç”¨æ–‡ä»¶
- `src/api/**/*.ts`
- `src/services/**/*.ts`
## å»ºè®®æ­¥éª¤
1. å®šä¹‰è¯·æ±‚/响应的 TypeScript æŽ¥å£
2. åˆ›å»ºå¸¦ç±»åž‹æ–¹æ³•çš„ API æœåŠ¡å¯¹è±¡
3. å¯¼å‡ºç±»åž‹å’ŒæœåŠ¡
4. å¦‚需要,添加错误处理
## API æœåŠ¡æ¨¡æ¿
```typescript
// types.ts
export interface User {
  id: number;
  name: string;
  email: string;
  createdAt: string;
}
export interface UserQuery {
  page?: number;
  pageSize?: number;
  name?: string;
}
export interface CreateUserDTO {
  name: string;
  email: string;
}
export interface UserListResponse {
  list: User[];
  total: number;
}
// user.ts
import { request } from '#/utils/request';
import type { User, UserQuery, CreateUserDTO, UserListResponse } from './types';
export const userApi = {
  // èŽ·å–ç”¨æˆ·åˆ—è¡¨
  getList: (params?: UserQuery) =>
    request.get<UserListResponse>('/users', { params }),
  // æ ¹æ®ID获取用户
  getById: (id: number) =>
    request.get<User>(`/users/${id}`),
  // åˆ›å»ºç”¨æˆ·
  create: (data: CreateUserDTO) =>
    request.post<User>('/users', data),
  // æ›´æ–°ç”¨æˆ·
  update: (id: number, data: Partial<CreateUserDTO>) =>
    request.put<User>(`/users/${id}`, data),
  // åˆ é™¤ç”¨æˆ·
  delete: (id: number) =>
    request.delete<void>(`/users/${id}`),
};
```
## å…¸åž‹æäº¤ä¿¡æ¯
- feat: add [模块名] API service
- feat: implement [模块名] API with types
.claude/database-migration.md
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,36 @@
---
name: database-migration
description: Workflow command scaffold for database-migration in everything-claude-code.
allowed_tools: ["Bash", "Read", "Write", "Grep", "Glob"]
---
# /database-migration
Use this workflow when working on **database-migration** in `everything-claude-code`.
## Goal
Database schema changes with migration files
## Common Files
- `**/schema.*`
- `migrations/*`
## Suggested Sequence
1. Understand the current state and failure mode before editing.
2. Make the smallest coherent change that satisfies the workflow goal.
3. Run the most relevant verification for touched files.
4. Summarize what changed and what still needs review.
## Typical Commit Signals
- Create migration file
- Update schema definitions
- Generate/update types
## Notes
- Treat this as a scaffold, not a hard-coded script.
- Update the command if the workflow evolves materially.
.claude/feature-development.md
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,38 @@
---
name: feature-development
description: Workflow command scaffold for feature-development in everything-claude-code.
allowed_tools: ["Bash", "Read", "Write", "Grep", "Glob"]
---
# /feature-development
Use this workflow when working on **feature-development** in `everything-claude-code`.
## Goal
Standard feature implementation workflow
## Common Files
- `manifests/*`
- `schemas/*`
- `**/*.test.*`
- `**/api/**`
## Suggested Sequence
1. Understand the current state and failure mode before editing.
2. Make the smallest coherent change that satisfies the workflow goal.
3. Run the most relevant verification for touched files.
4. Summarize what changed and what still needs review.
## Typical Commit Signals
- Add feature implementation
- Add tests for feature
- Update documentation
## Notes
- Treat this as a scaffold, not a hard-coded script.
- Update the command if the workflow evolves materially.
.claude/pinia-store.md
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,99 @@
---
name: pinia-store
description: åˆ›å»ºæ–°çš„ Pinia çŠ¶æ€å­˜å‚¨ï¼ŒåŒ…å« TypeScript ç±»åž‹
allowed_tools: ["Bash", "Read", "Write", "Grep", "Glob"]
---
# /pinia-store
创建新的 Pinia çŠ¶æ€å­˜å‚¨æ—¶ä½¿ç”¨æ­¤å·¥ä½œæµã€‚
## ç›®æ ‡
使用 Composition API é£Žæ ¼åˆ›å»ºç±»åž‹å®‰å…¨çš„ Pinia çŠ¶æ€å­˜å‚¨ã€‚
## å¸¸ç”¨æ–‡ä»¶
- `src/stores/**/*.ts`
- `src/**/store.ts`
## å»ºè®®æ­¥éª¤
1. å®šä¹‰çŠ¶æ€æŽ¥å£
2. ä½¿ç”¨ setup è¯­æ³•创建 store
3. æ·»åŠ è®¡ç®—å±žæ€§ï¼ˆgetters)
4. æ·»åŠ æ“ä½œæ–¹æ³•ï¼ˆactions)
5. å¦‚需要,配置持久化
## Pinia Store æ¨¡æ¿
```typescript
// stores/user.ts
import { ref, computed } from 'vue';
import { defineStore } from 'pinia';
import type { User } from '#/api/types';
interface UserState {
  user: User | null;
  token: string | null;
}
export const useUserStore = defineStore(
  'user',
  () => {
    // çŠ¶æ€
    const user = ref<User | null>(null);
    const token = ref<string | null>(null);
    // è®¡ç®—属性 (Getters)
    const isLoggedIn = computed(() => !!token.value && !!user.value);
    const userName = computed(() => user.value?.name ?? '');
    const userRoles = computed(() => user.value?.roles ?? []);
    // æ“ä½œæ–¹æ³• (Actions)
    const setUser = (newUser: User) => {
      user.value = newUser;
    };
    const setToken = (newToken: string) => {
      token.value = newToken;
    };
    const logout = () => {
      user.value = null;
      token.value = null;
    };
    const hasRole = (role: string) => {
      return userRoles.value.includes(role);
    };
    return {
      // çŠ¶æ€
      user,
      token,
      // è®¡ç®—属性
      isLoggedIn,
      userName,
      userRoles,
      // æ“ä½œæ–¹æ³•
      setUser,
      setToken,
      logout,
      hasRole,
    };
  },
  {
    persist: {
      key: 'user-store',
      storage: localStorage,
      pick: ['token'], // åªæŒä¹…化 token,不持久化用户对象
    },
  }
);
```
## å…¸åž‹æäº¤ä¿¡æ¯
- feat: add [Store名] store
- feat: implement [Store名] state management
.claude/settings.local.json
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,9 @@
{
  "permissions": {
    "allow": [
      "WebFetch(domain:github.com)",
      "Bash(gh repo *)",
      "WebSearch"
    ]
  }
}
.claude/skills/antd-vue-components/SKILL.md
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,212 @@
---
name: antd-vue-components
description: Ant Design Vue ç»„件开发模式和最佳实践
---
# Ant Design Vue ç»„件技能
## ä½•时使用
在以下场景激活此技能:
- ä½¿ç”¨ Ant Design Vue ç»„件构建表单
- åˆ›å»º Vxe-Table æˆ– Ant Design è¡¨æ ¼
- å®žçŽ°æ¨¡æ€æ¡†å’ŒæŠ½å±‰ç»„ä»¶
- ä½¿ç”¨ Ant Design è¡¨å•验证
- è‡ªå®šä¹‰ Ant Design ä¸»é¢˜
## å·¥ä½œåŽŸç†
此技能为 Ant Design Vue 4.x å¼€å‘模式提供指导。
## æŠ€æœ¯æ ˆ
- **Ant Design Vue**: 4.2.x
- **Vxe-Table**: 4.19.x(用于复杂表格)
- **表单验证**: VeeValidate + Zod schema
- **图标**: @iconify/vue å’Œ @lucide/vue
## å¸¸ç”¨æ¨¡å¼
### å¸¦éªŒè¯çš„表单
```vue
<script setup lang="ts">
import { useForm } from 'vee-validate';
import { toTypedSchema } from '@vee-validate/zod';
import { z } from 'zod';
const schema = toTypedSchema(
  z.object({
    username: z.string().min(3, '用户名至少3个字符'),
    email: z.string().email('邮箱格式不正确'),
    role: z.enum(['admin', 'user', 'guest']),
  })
);
const { handleSubmit, setFieldValue, values } = useForm({
  validationSchema: schema,
  initialValues: {
    username: '',
    email: '',
    role: 'user',
  },
});
const onSubmit = handleSubmit(async (values) => {
  // ç±»åž‹å®‰å…¨çš„ values
  console.log(values);
});
</script>
<template>
  <a-form @submit="onSubmit">
    <a-form-item label="用户名" name="username">
      <a-input v-model:value="values.username" />
    </a-form-item>
    <a-form-item label="邮箱" name="email">
      <a-input v-model:value="values.email" type="email" />
    </a-form-item>
    <a-form-item label="角色" name="role">
      <a-select v-model:value="values.role">
        <a-select-option value="admin">管理员</a-select-option>
        <a-select-option value="user">用户</a-select-option>
        <a-select-option value="guest">访客</a-select-option>
      </a-select>
    </a-form-item>
    <a-button type="primary" html-type="submit">提交</a-button>
  </a-form>
</template>
```
### å¸¦æ“ä½œåˆ—的表格
```vue
<script setup lang="ts">
import { ref, computed } from 'vue';
import type { TableColumn } from '#/types';
interface User {
  id: number;
  name: string;
  email: string;
  status: 'active' | 'inactive';
}
const columns: TableColumn<User>[] = [
  { title: '姓名', dataIndex: 'name', key: 'name' },
  { title: '邮箱', dataIndex: 'email', key: 'email' },
  {
    title: '状态',
    dataIndex: 'status',
    key: 'status',
    customRender: ({ text }) => text === 'active' ? '启用' : '禁用',
  },
  {
    title: '操作',
    key: 'actions',
    width: 150,
  },
];
const dataSource = ref<User[]>([]);
const loading = ref(false);
const handleEdit = (record: User) => {
  // ç¼–辑逻辑
};
const handleDelete = (id: number) => {
  // åˆ é™¤é€»è¾‘
};
</script>
<template>
  <a-table
    :columns="columns"
    :data-source="dataSource"
    :loading="loading"
    row-key="id"
  >
    <template #bodyCell="{ column, record }">
      <template v-if="column.key === 'actions'">
        <a-space>
          <a-button type="link" @click="handleEdit(record)">编辑</a-button>
          <a-popconfirm
            title="确定要删除吗?"
            @confirm="handleDelete(record.id)"
          >
            <a-button type="link" danger>删除</a-button>
          </a-popconfirm>
        </a-space>
      </template>
    </template>
  </a-table>
</template>
```
### æ¨¡æ€æ¡†
```vue
<script setup lang="ts">
import { ref } from 'vue';
const visible = ref(false);
const loading = ref(false);
const open = () => {
  visible.value = true;
};
const handleOk = async () => {
  loading.value = true;
  try {
    // ä¿å­˜é€»è¾‘
    visible.value = false;
  } finally {
    loading.value = false;
  }
};
const handleCancel = () => {
  visible.value = false;
};
defineExpose({ open });
</script>
<template>
  <a-modal
    v-model:open="visible"
    title="对话框标题"
    :confirm-loading="loading"
    @ok="handleOk"
    @cancel="handleCancel"
  >
    <p>模态框内容</p>
  </a-modal>
</template>
```
## æœ€ä½³å®žè·µ
### æŽ¨è
- å¤æ‚表单验证使用 VeeValidate + Zod
- Ant Design è¾“入框使用 `v-model:value`
- åœ¨æ¨¡æ¿å¤–解构表格列定义
- å±é™©æ“ä½œä½¿ç”¨ `a-popconfirm` ç¡®è®¤
- è®¾ç½®è¡¨æ ¼ `row-key` æå‡æ€§èƒ½
### é¿å…
- ä¸è¦æ··ç”¨ Ant Design 3.x å’Œ 4.x API
- ä¸è¦å¿˜è®°å¤„理加载状态
- ä¸è¦ä½¿ç”¨å†…联样式 - ä½¿ç”¨ Tailwind æˆ– scoped CSS
## Vxe-Table å¤æ‚表格
以下场景使用 Vxe-Table:
- å¤§æ•°æ®é›†è™šæ‹Ÿæ»šåЍ
- Excel é£Žæ ¼ç¼–辑
- å¤æ‚单元格合并
- æ ‘形数据展开/折叠
.claude/skills/frontend-code-review/SKILL.md
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,168 @@
---
name: frontend-code-review
description: Vue 3 + TypeScript é¡¹ç›®å‰ç«¯ä»£ç å®¡æŸ¥æŒ‡å—
---
# å‰ç«¯ä»£ç å®¡æŸ¥æŠ€èƒ½
## ä½•时使用
在以下场景激活此技能:
- å®¡æŸ¥ Pull Request
- è¿›è¡Œ Vue ç»„件代码审查
- æ£€æŸ¥å®‰å…¨æ¼æ´ž
- éªŒè¯ TypeScript ç±»åž‹å®‰å…¨
- å®¡æŸ¥æ€§èƒ½ä¼˜åŒ–
## å·¥ä½œåŽŸç†
此技能提供前端代码审查的检查清单和指南。
## å®¡æŸ¥æ¸…单
### TypeScript å’Œç±»åž‹
- [ ] æ²¡æœ‰ä¸åˆç†çš„ `any` ç±»åž‹
- [ ] Props å’Œ Emits æœ‰æ­£ç¡®çš„ TypeScript æŽ¥å£
- [ ] API å“åº”有类型接口
- [ ] æ­£ç¡®ä½¿ç”¨æ³›åž‹
- [ ] ç±»åž‹å¯¼å…¥ä½¿ç”¨ `import type` è¯­æ³•
### Vue ç»„ä»¶
- [ ] ä½¿ç”¨ `<script setup>` è¯­æ³•
- [ ] å¯é€‰ Props æœ‰é»˜è®¤å€¼
- [ ] Emits ä½¿ç”¨ TypeScript ç±»åž‹
- [ ] æ²¡æœ‰ç›´æŽ¥ä¿®æ”¹ props
- [ ] æ­£ç¡®ä½¿ç”¨ `computed` vs `watch`
- [ ] åœ¨ `onUnmounted` ä¸­æ¸…理副作用
### å®‰å…¨æ€§
- [ ] æ²¡æœ‰ XSS æ¼æ´žï¼ˆç”¨æˆ·å†…容使用 `v-dompurify-html`)
- [ ] æ²¡æœ‰ç¡¬ç¼–码的密钥或 API Key
- [ ] ç”¨æˆ·è¾“入已过滤
- [ ] æ•æ„Ÿæ•°æ®ä¸åœ¨ localStorage(使用 secure-ls æˆ– sessionStorage)
- [ ] CSRF token æ­£ç¡®å¤„理
### æ€§èƒ½
- [ ] å¤§åˆ—表使用虚拟滚动
- [ ] å›¾ç‰‡å·²ä¼˜åŒ–
- [ ] è·¯ç”±æ‡’加载
- [ ] æ²¡æœ‰ä¸å¿…要的重渲染
- [ ] æ­£ç¡®ä½¿ç”¨ `v-memo` å’Œ `v-once`
### å¯è®¿é—®æ€§
- [ ] æ­£ç¡®çš„ ARIA å±žæ€§
- [ ] é”®ç›˜å¯¼èˆªå¯ç”¨
- [ ] é¢œè‰²å¯¹æ¯”度足够
- [ ] æ¨¡æ€æ¡†ç„¦ç‚¹ç®¡ç†
### ä»£ç è´¨é‡
- [ ] å‡½æ•°èŒè´£å•一
- [ ] æ²¡æœ‰é‡å¤ä»£ç ï¼ˆæå–到组合式函数)
- [ ] é”™è¯¯å¤„理完善
- [ ] åŠ è½½çŠ¶æ€å·²å¤„ç†
- [ ] è¾¹ç•Œæƒ…况已考虑
## å¸¸è§é—®é¢˜æ ‡è®°
### 1. ç›´æŽ¥ä¿®æ”¹ Props
```typescript
// é”™è¯¯
props.value = newValue;
// æ­£ç¡®
emit('update:value', newValue);
```
### 2. å†…存泄漏
```typescript
// é”™è¯¯ - æ²¡æœ‰æ¸…理
onMounted(() => {
  window.addEventListener('resize', handleResize);
});
// æ­£ç¡® - ç»„件卸载时清理
onMounted(() => {
  window.addEventListener('resize', handleResize);
});
onUnmounted(() => {
  window.removeEventListener('resize', handleResize);
});
```
### 3. ä¸å¿…要的响应式
```typescript
// é”™è¯¯ - é™æ€æ•°æ®ä¸éœ€è¦å“åº”式
const menuItems = reactive([
  { label: '首页', path: '/' },
  { label: '关于', path: '/about' },
]);
// æ­£ç¡® - é™æ€æ•°æ®ä¸éœ€è¦å“åº”式
const menuItems = [
  { label: '首页', path: '/' },
  { label: '关于', path: '/about' },
];
```
### 4. ç¼ºå°‘错误边界
```vue
<!-- é”™è¯¯ - æ²¡æœ‰é”™è¯¯å¤„理 -->
<template>
  <ExpensiveComponent />
</template>
<!-- æ­£ç¡® - æœ‰é”™è¯¯è¾¹ç•Œ -->
<template>
  <ErrorBoundary>
    <ExpensiveComponent />
  </ErrorBoundary>
</template>
```
## å®‰å…¨çº¢çº¿
1. **XSS é£Žé™©**
   - ä½¿ç”¨ `v-html` ä½†æ²¡æœ‰è¿‡æ»¤
   - æ¸²æŸ“用户生成的内容
   - é€šè¿‡ `window.location` è¿›è¡Œ URL æ³¨å…¥
2. **数据泄露**
   - æŽ§åˆ¶å°è¾“出敏感数据
   - Token åœ¨ localStorage ä¸­æœªåР坆
   - æºä»£ç ä¸­æœ‰ API Key
3. **注入风险**
   - åŠ¨æ€ç»„ä»¶åæ¥è‡ªç”¨æˆ·è¾“å…¥
   - ä½¿ç”¨ `eval()` æˆ– `Function()`
   - API è°ƒç”¨ä¸­çš„ SQL æ³¨å…¥
## å®¡æŸ¥æ„è§æ ¼å¼
使用建设性的评论:
```markdown
**建议**: è¿™é‡Œè€ƒè™‘使用 `computed` æ›¿ä»£ `watch` ä»¥èŽ·å¾—æ›´å¥½çš„æ€§èƒ½ã€‚
```typescript
// å½“前代码
watch(() => props.value, (val) => {
  doubled.value = val * 2;
});
// å»ºè®®ä¿®æ”¹
const doubled = computed(() => props.value * 2);
```
原因: è®¡ç®—属性有缓存,只有依赖变化时才重新计算。
```
.claude/skills/vue3-development/SKILL.md
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,155 @@
---
name: vue3-development
description: Vue 3 + TypeScript + Composition API å¼€å‘规范和最佳实践
---
# Vue 3 å¼€å‘技能
## ä½•时使用
在以下场景激活此技能:
- ä½¿ç”¨ Composition API å¼€å‘ Vue 3 ç»„ä»¶
- ä¸º Vue åº”用编写 TypeScript ä»£ç 
- è®¾ç½® Pinia çŠ¶æ€å­˜å‚¨æˆ– Vue Router
- ä½¿ç”¨ç»„合式函数和响应式状态
- ä¼˜åŒ– Vue ç»„件性能
## å·¥ä½œåŽŸç†
此技能为 Vue 3 å¼€å‘模式提供指导。
## æŠ€æœ¯æ ˆ
- **Vue**: 3.5.x ä½¿ç”¨ Composition API
- **TypeScript**: å®Œæ•´ç±»åž‹å®‰å…¨
- **状态管理**: Pinia + persistedstate
- **路由**: Vue Router 5.x
- **表单验证**: VeeValidate + Zod
- **HTTP å®¢æˆ·ç«¯**: Axios
## ä»£ç é£Žæ ¼
### ç»„件结构
```vue
<script setup lang="ts">
import { ref, computed, onMounted } from 'vue';
import type { PropType } from 'vue';
// ä½¿ç”¨ TypeScript å®šä¹‰ Props
interface Props {
  title: string;
  items?: string[];
}
const props = withDefaults(defineProps<Props>(), {
  items: () => [],
});
// ä½¿ç”¨ TypeScript å®šä¹‰ Emits
interface Emits {
  (e: 'update', value: string): void;
  (e: 'delete', id: number): void;
}
const emit = defineEmits<Emits>();
// å“åº”式状态
const isLoading = ref(false);
const localData = ref<string | null>(null);
// è®¡ç®—属性
const formattedTitle = computed(() => props.title.toUpperCase());
// æ–¹æ³•
const handleSubmit = async () => {
  isLoading.value = true;
  try {
    // ...
  } finally {
    isLoading.value = false;
  }
};
// ç”Ÿå‘½å‘¨æœŸ
onMounted(() => {
  // åˆå§‹åŒ–
});
</script>
<template>
  <div class="component-wrapper">
    <h1>{{ formattedTitle }}</h1>
    <slot />
  </div>
</template>
<style scoped>
.component-wrapper {
  /* scoped æ ·å¼ */
}
</style>
```
### ç»„合式函数模式
```typescript
// composables/useUser.ts
import { ref, computed } from 'vue';
import { defineStore } from 'pinia';
export const useUserStore = defineStore('user', () => {
  const user = ref<User | null>(null);
  const isLoggedIn = computed(() => !!user.value);
  const login = async (credentials: LoginCredentials) => {
    // å®žçް
  };
  const logout = () => {
    user.value = null;
  };
  return { user, isLoggedIn, login, logout };
});
```
### API é›†æˆ
```typescript
// api/user.ts
import { request } from '#/utils/request';
export const userApi = {
  getList: (params: UserQuery) => request.get<UserList>('/users', { params }),
  getById: (id: number) => request.get<User>(`/users/${id}`),
  create: (data: CreateUserDTO) => request.post<User>('/users', data),
  update: (id: number, data: UpdateUserDTO) => request.put<User>(`/users/${id}`, data),
  delete: (id: number) => request.delete(`/users/${id}`),
};
```
## æœ€ä½³å®žè·µ
### æŽ¨è
- æ‰€æœ‰ç»„件使用 `<script setup>` è¯­æ³•
- ä½¿ç”¨ TypeScript æŽ¥å£å®šä¹‰ props å’Œ emits
- ä½¿ç”¨ç»„合式函数复用逻辑
- å°½å¯èƒ½ä½¿ç”¨ `computed` è€Œéž `watch`
- è·¯ç”±çº§ç»„件使用 `defineAsyncComponent` æ‡’加载
- ä¿æŒç»„件职责单一
### é¿å…
- ä¸è¦ä½¿ç”¨ Options API(推荐 Composition API)
- ä¸è¦ç›´æŽ¥ä¿®æ”¹ props
- ä¸è¦ä½¿ç”¨ `any` ç±»åž‹ - å®šä¹‰æ­£ç¡®çš„æŽ¥å£
- ä¸è¦å¿˜è®°åœ¨ `onUnmounted` ä¸­æ¸…理副作用
## æ€§èƒ½ä¼˜åŒ–建议
1. å¯¹äºŽä¸éœ€è¦æ·±åº¦å“åº”的大型对象使用 `shallowRef`
2. å¯¹äºŽæ˜‚贵的列表渲染使用 `v-memo`
3. ä½¿ç”¨ `defineAsyncComponent` æ‡’加载组件
4. å¯¹äºŽé™æ€å†…容使用 `v-once`
.claude/vue-component.md
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,87 @@
---
name: vue-component
description: åˆ›å»ºæ–°çš„ Vue 3 ç»„件,包含 TypeScript ç±»åž‹å®šä¹‰å’Œæœ€ä½³å®žè·µ
allowed_tools: ["Bash", "Read", "Write", "Grep", "Glob"]
---
# /vue-component
创建新的 Vue 3 ç»„件时使用此工作流。
## ç›®æ ‡
创建一个结构良好的 Vue 3 ç»„件,包含 TypeScript ç±»åž‹ã€æ­£ç¡®çš„ props/emit å®šä¹‰ï¼Œå¹¶éµå¾ªé¡¹ç›®è§„范。
## å¸¸ç”¨æ–‡ä»¶
- `src/components/**/*.vue`
- `src/views/**/*.vue`
- `src/**/components/*.vue`
## å»ºè®®æ­¥éª¤
1. æ ¹æ®ä½œç”¨åŸŸç¡®å®šç»„件位置(全局组件 vs åŠŸèƒ½ç»„ä»¶ï¼‰
2. åˆ›å»º `.vue` æ–‡ä»¶ï¼Œä½¿ç”¨ `<script setup lang="ts">`
3. å®šä¹‰ Props å’Œ Emits çš„ TypeScript æŽ¥å£
4. ä½¿ç”¨ Composition API å®žçŽ°ç»„ä»¶é€»è¾‘
5. æ·»åŠ æ¨¡æ¿å’Œæ­£ç¡®çš„ç»‘å®š
6. å¦‚需要,添加 scoped æ ·å¼
7. å¯¼å‡ºç»„件供使用
## ç»„件模板
```vue
<script setup lang="ts">
import { ref, computed } from 'vue';
// Props å®šä¹‰
interface Props {
  title: string;
  disabled?: boolean;
}
const props = withDefaults(defineProps<Props>(), {
  disabled: false,
});
// Emits å®šä¹‰
interface Emits {
  (e: 'click', value: string): void;
}
const emit = defineEmits<Emits>();
// å“åº”式状态
const isActive = ref(false);
// æ–¹æ³•
const handleClick = () => {
  if (!props.disabled) {
    isActive.value = !isActive.value;
    emit('click', props.title);
  }
};
</script>
<template>
  <div
    class="component-name"
    :class="{ 'is-active': isActive, 'is-disabled': disabled }"
    @click="handleClick"
  >
    <span>{{ title }}</span>
    <slot />
  </div>
</template>
<style scoped>
.component-name {
  /* æ ·å¼ */
}
</style>
```
## å…¸åž‹æäº¤ä¿¡æ¯
- feat: add [组件名] component
- feat: implement [组件名] for [功能名]
.claude/vue-page.md
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,95 @@
---
name: vue-page
description: åˆ›å»ºæ–°çš„页面/视图,包含 Vue Router è·¯ç”±é…ç½®
allowed_tools: ["Bash", "Read", "Write", "Grep", "Glob"]
---
# /vue-page
创建新的页面/视图时使用此工作流。
## ç›®æ ‡
创建新的页面组件并在 Vue Router ä¸­æ³¨å†Œè·¯ç”±ã€‚
## å¸¸ç”¨æ–‡ä»¶
- `src/views/**/*.vue`
- `src/router/routes/**/*.ts`
## å»ºè®®æ­¥éª¤
1. åœ¨ `src/views/` ä¸‹åˆ›å»ºé¡µé¢ç»„ä»¶
2. å®šä¹‰è·¯ç”±é…ç½®
3. å°†è·¯ç”±æ·»åŠ åˆ°è·¯ç”±å™¨
4. å¦‚需要,添加页面标题和 meta ä¿¡æ¯
## é¡µé¢æ¨¡æ¿
```vue
<script setup lang="ts">
import { ref, onMounted } from 'vue';
import { useRoute } from 'vue-router';
defineOptions({
  name: 'PageName',
});
const route = useRoute();
const loading = ref(false);
onMounted(() => {
  // åˆå§‹åŒ–页面数据
});
</script>
<template>
  <div class="page-container">
    <a-spin :spinning="loading">
      <!-- é¡µé¢å†…容 -->
      <h1>页面标题</h1>
    </a-spin>
  </div>
</template>
<style scoped>
.page-container {
  padding: 16px;
}
</style>
```
## è·¯ç”±é…ç½®
```typescript
// router/routes/module.ts
import type { RouteRecordRaw } from 'vue-router';
const routes: RouteRecordRaw[] = [
  {
    path: '/module',
    name: 'ModuleList',
    component: () => import('#/views/module/index.vue'),
    meta: {
      title: '模块列表',
      icon: 'mdi:list',
    },
  },
  {
    path: '/module/:id',
    name: 'ModuleDetail',
    component: () => import('#/views/module/detail.vue'),
    meta: {
      title: '模块详情',
      hideMenu: true,
    },
  },
];
export default routes;
```
## å…¸åž‹æäº¤ä¿¡æ¯
- feat: add [页面名] page
- feat: implement [页面名] view
CLAUDE.md
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,94 @@
# é¡¹ç›®æŒ‡å—
这是基于 **Vue Vben Admin** çš„前端项目,使用 Vue 3 + TypeScript + Vite + Ant Design Vue。
## æŠ€æœ¯æ ˆ
- **框架**: Vue 3.5 + TypeScript 6.0
- **构建工具**: Vite 8.0
- **UI ç»„ä»¶**: Ant Design Vue 4.2
- **状态管理**: Pinia 3.0 + persistedstate
- **路由**: Vue Router 5.1
- **表单验证**: VeeValidate + Zod
- **HTTP å®¢æˆ·ç«¯**: Axios
- **样式**: Tailwind CSS 4.3 + SCSS
- **图表**: ECharts 6.1
- **富文本编辑器**: TinyMCE 7.9, Tiptap 3.26
- **流程图**: BPMN.js 18.16
## é¡¹ç›®ç»“æž„
```
src/
├── api/              # API æŽ¥å£å®šä¹‰
├── components/       # å…¬å…±ç»„ä»¶
├── composables/      # ç»„合式函数
├── layouts/          # å¸ƒå±€ç»„ä»¶
├── locales/          # å›½é™…化
├── router/           # è·¯ç”±é…ç½®
├── stores/           # Pinia çŠ¶æ€ç®¡ç†
├── styles/           # å…¨å±€æ ·å¼
├── utils/            # å·¥å…·å‡½æ•°
└── views/            # é¡µé¢ç»„ä»¶
```
## å¼€å‘命令
```bash
# å¼€å‘
pnpm dev
# æž„建
pnpm build
# ç±»åž‹æ£€æŸ¥
pnpm typecheck
# é¢„览构建结果
pnpm preview
```
## ä»£ç è§„范
### ç»„件命名
- ç»„件文件使用 PascalCase: `UserList.vue`
- ç»„ä»¶ name ä½¿ç”¨ PascalCase: `defineOptions({ name: 'UserList' })`
### TypeScript
- ç¦æ­¢ä½¿ç”¨ `any` ç±»åž‹
- Props å’Œ Emits å¿…须定义 TypeScript æŽ¥å£
- ä½¿ç”¨ `import type` å¯¼å…¥ç±»åž‹
### Vue ç»„ä»¶
- ç»Ÿä¸€ä½¿ç”¨ `<script setup lang="ts">` è¯­æ³•
- Props ä½¿ç”¨ `withDefaults` + `defineProps<T>()`
- Emits ä½¿ç”¨ `defineEmits<T>()`
### æ ·å¼
- ä¼˜å…ˆä½¿ç”¨ Tailwind CSS ç±»
- ç»„件样式使用 `scoped`
- é¢œè‰²ä½¿ç”¨ CSS å˜é‡
## å¯ç”¨å‘½ä»¤
- `/vue-component` - åˆ›å»ºæ–°çš„ Vue ç»„ä»¶
- `/vue-page` - åˆ›å»ºæ–°çš„页面
- `/api-service` - åˆ›å»º API æœåŠ¡æ¨¡å—
- `/pinia-store` - åˆ›å»º Pinia çŠ¶æ€å­˜å‚¨
## å¯ç”¨æŠ€èƒ½
- `vue3-development` - Vue 3 å¼€å‘规范
- `antd-vue-components` - Ant Design Vue ç»„件模式
- `frontend-code-review` - å‰ç«¯ä»£ç å®¡æŸ¥æŒ‡å—
## æ³¨æ„äº‹é¡¹
1. è·¯å¾„别名 `#/*` æŒ‡å‘ `./src/*`
2. ä½¿ç”¨ VeeValidate + Zod è¿›è¡Œè¡¨å•验证
3. ä½¿ç”¨ `v-dompurify-html` å¤„理用户输入的 HTML
4. æ•æ„Ÿæ•°æ®ä½¿ç”¨ `secure-ls` åŠ å¯†å­˜å‚¨