--- name: component-scaffold version: 4.1.0 description: "生成 Vue 3 SFC 组件脚手架,含单元测试和类型安全 Props。当需要新建组件、拆分子组件或创建复合组件时使用。管理端用 Element Plus,用户端用 Headless UI。" requires: [vue-testing] --- > ⚠️ 核心执行流程已在 `.cursor/rules/skill-component-scaffold.mdc` 中由 Cursor 自动注入。 > 本文件提供完整模板、代码示例和边缘场景处理,供 Agent 按需深入 Read。 # Vue 3 Component Scaffold > **⚠️ 前端识别**:生成组件前必须确认目标前端。 > - **管理端** (`Case-Database-Frontend-admin/`):使用 Element Plus + Tailwind > - **用户端** (`Case-Database-Frontend-user/`):使用 Headless UI + Tailwind,**禁止 Element Plus** ## 触发条件 用户要求创建新的 Vue 组件、页面组件、UI 元素或交互模块。 ## 执行流程 ### 0. 加载规范(⚠️ 必须最先执行) 依次读取 `.cursor/rules/010-typescript.mdc`、`.cursor/rules/011-vue.mdc`、`.cursor/rules/019-modular.mdc`,提取类型注解要求(隐式 any 禁令、ref 泛型规范、Composable 类型规范)、script setup、defineProps/Emits、组件分类、拆分阈值、Composable 提取规则。 > **Tier 3**:Vue 3 完整 API 见 `references/vue-api-reference.md`。 ### 0.5 ⚠️ 生成前强制结构规划(禁止跳过) **写代码前必须先输出文件结构和组件职责说明。** #### A. 检查是否已有可复用的基础组件 在生成新组件前,先扫描以下路径,**避免重复造轮子**: - `src/components/core/` — 通用基础组件(按钮、输入框、卡片等) - `src/components/custom/` — 业务定制组件 若已有 `FormInput.vue`、`BaseCard.vue` 等,**直接复用,不重新生成**。 #### B. 用户端表单输入:优先复用 FormInput 模式 用户端页面中表单输入框若出现 ≥3 个,必须使用 `FormInput` 基础组件: ```vue ``` > 若项目中尚无 `FormInput`,在生成使用它的页面前先生成该核心组件。 #### C. 重复 UI 模式检测 检查需求中是否存在重复结构: | 场景 | 检测标准 | 操作 | |------|---------|------| | 表单输入项 | ≥3 个相同结构的 input 组 | 提取 `FormInput.vue` | | 内容卡片 | ≥3 个相同布局的卡片 | 提取 `CaseCard.vue` / `DesignerCard.vue` | | 操作按钮组 | ≥2 处相同按钮组合 | 提取 `ActionGroup.vue` | | 阶段/Tab 面板 | ≥2 个结构相同的面板 | 提取 `StagePanel.vue` | #### D. 输出组件文件结构(代码前必须输出) ``` # 本次将生成以下文件: src/components/// ├── .vue ← 主组件(目标 ≤ 120 行) ├── .test.ts ← 单元测试 └── index.ts ← barrel export # 依赖(已存在 / 需新建): - FormInput.vue: [已存在 / 需新建] - BaseCard.vue: [已存在 / 不需要] ``` --- ### 1. 确认组件规格 | 字段 | 必填 | 默认值 | |------|------|--------| | 组件名 | ✅ | — | | 组件类型 | ❌ | UI 组件 | | 所在目录 | ❌ | `src/components/` | | Props / Emits | ❌ | 根据需求推断 | 类型与目录:`core`→`src/components/core/`、`custom`→`custom/`、`layout`→`layouts/`、`page`→`views//components/`、`form`→`custom/`。 ### 2. 扫描项目模式 读取 `src/components/` 确认 Props 声明、样式方案、命名前缀约定、已有的 core 组件列表。 ### 3. 生成文件结构 按步骤 0.5 输出的结构逐文件生成,**禁止将多个组件合并到一个文件**。 ``` src/components/// ├── .vue ├── .test.ts └── index.ts ``` ### 4. 组件模板 根据类型选择:基础 UI / 表格 / 表单对话框 / 复合组件。完整模板与设计决策树见 **Tier 3**。 **单组件行数限制**: - template 区域 ≤ 80 行 - script 区域 ≤ 60 行(超出提取 composable) - 整个 SFC ≤ 150 行(超出必须拆分子组件) ### 4.5 设计决策树(必须执行) - ≥3 布尔 prop?→ 显式变体组件 - 多子组件共享状态?→ provide/inject - script 逻辑 > 60 行?→ 提取 `use.ts` composable(**必须遵循 `010-typescript.mdc` 的 Composable 类型规范**:参数有类型、`ref` 有泛型、业务类型用 `import type`) - >2 处复用?→ `src/components/` + slot - 同一 UI 结构重复 ≥3 次?→ 提取基础组件(见步骤 0.5C) - 否则 → 基础 UI 模板 ### 5. 测试与 Barrel export 测试至少包含渲染测试。`index.ts` 导出:`export { default as ComponentName } from './ComponentName.vue'`。详细测试见 `vue-testing` 技能。 ## 验证 1. [ ] ESLint 无报错 2. [ ] Props 使用对象语法 `defineProps({ key: { type, default } })`,**若模板可直接访问 props 字段则不保存返回值**(避免 `unused-vars` 报错;仅当 script 中需要访问 `props.xxx` 时才保存:`const props = defineProps(...)`) 3. [ ] Emits 使用数组语法,事件名使用 camelCase(非 kebab-case) 4. [ ] 包含 `data-testid` 5. [ ] 测试至少一个渲染测试 6. [ ] 管理端:Element Plus 用于组件,Tailwind 用于布局;用户端:Headless UI + Tailwind(禁止 Element Plus) 7. [ ] barrel export 正确 8. [ ] **单 SFC ≤ 150 行** 9. [ ] **重复 UI 结构(≥3 次)已提取为基础组件** 10. [ ] **表单输入 ≥3 个已复用 FormInput.vue**(用户端) 11. [ ] **子组件模板中无 `v-model` 直接绑定 prop 嵌套属性**(参见 `011-vue.mdc` Props 数据流模式) 12. [ ] **提取的 composable(use*.ts)参数有类型注解、`ref([])` / `ref(null)` 有泛型标注**(参见 `010-typescript.mdc` Composable 类型规范) ### Red Flags(触发则停止并重构) - ❌ 未输出文件结构直接写代码 → 停止,先输出步骤 0.5D 的结构 - ❌ 单 SFC > 150 行 → 拆分子组件 - ❌ 相同 Tailwind 输入框结构写了 ≥3 次 → 提取 FormInput.vue - ❌ Options API → 改用 `