newlifex/newlife.cube/vue-component-visual-loop

Claude Code and agent skill by newlifex/newlife.cube

Trust tier 3
  • community
Source check pending

Checking that the SKILL.md file is still in the repository.

Vue 组件开发的「视觉快速迭代闭环」:Gallery 手动预览(?story= 深链 / 无参数侧栏,带 HMR)+ Vitest 逻辑回归 + Playwright CT 像素级截图。提供手动浏览器预览与 CT 测试编写规范,让"改代码→截图→调整→再截图"在分钟级闭环中完成。

Install

npx vskill@latest install newlifex/newlife.cube/vue-component-visual-loop

SKILL.md

组件视觉快速迭代闭环(vue-component-visual-loop)

适用场景:开发 Vue 组件时,遵循「改代码 → 逻辑回归 → 视觉预览 → 截图锁定 → 循环」的闭环。
核心原则:组件只负责 UI 和事件,逻辑抽到纯函数 / Hook。Vitest 守住逻辑不退化,Playwright CT 守住视觉不跑偏——两者不是独立路径,而是同一循环的两个阶段。
闭环为何快:不必启动完整 SPA / 不必手搓演示页——Gallery 通过 Vite 直接渲染真实 .vue 组件,改完即 HMR 热更新,浏览器里秒看效果;逻辑改动用 Vitest 秒级回归,视觉改动用 CT 像素级兜底。
前置约束:关注点分离(*.logic.ts 纯函数、<script setup> 精简)与测试策略,详见项目 AGENTS.md / 测试规范。

一、闭环总览(渐进式开发循环)

┌───────────────────────────────────────────────────────────────┐
│ 1. 写代码 │
│ • 组件只放 template + <script setup>(精简) │
│ • 业务逻辑抽到同目录 *.logic.ts 纯函数 / use*.ts Hook │
│ • 组件通过 emit 上报事件,父级或 logic 层处理 │
└───────────────────────┬───────────────────────────────────────┘
▼
┌───────────────────────────────────────────────────────────────┐
│ 2. test:unit ← Vitest 逻辑回归(~5s,快速反馈) │
│ ❌ 失败 → 分析断言 → 回第 1 步 ✅ 通过 → 进视觉阶段 │
└───────────────────────┬───────────────────────────────────────┘
▼
┌───────────────────────────────────────────────────────────────┐
│ 3. ct:server ← 手动浏览器预览(HMR,分钟级视觉迭代) │
│ 浏览器开根目录 /(无参数=侧栏 / ?story=单故事,index.html 即 gallery 宿主) │
│ ❌ 不满意 → 改 .vue(HMR 自动刷新)→ 再看 ✅ 满意 → 锁基线 │
└───────────────────────┬───────────────────────────────────────┘
▼
┌───────────────────────────────────────────────────────────────┐
│ 4. test:ct:dev ← Playwright CT 截图(有头浏览器) │
│ ❌ 不满意 → 回第 1 步 ✅ 满意 → 确立基线 │
└───────────────────────┬───────────────────────────────────────┘
▼
┌───────────────────────────────────────────────────────────────┐
│ 5. test:ct:update ← 确立基线,锁定当前效果 │
│ 以后 test:ct 做回归保护,防止被改坏 │
└───────────────────────────────────────────────────────────────┘

二、文件清单与职责

为组件 <ComponentName> 新增验证闭环,需要以下文件:

core/components/<ComponentName>/
├── <ComponentName>.vue # 组件实现(只负责 UI + emit)
├── <ComponentName>.logic.ts # [可选] 业务逻辑纯函数(或 use<Name>.ts 组合式 Hook)
├── <ComponentName>.spec.ts # Vitest 回归测试(逻辑 + emit + 边界)
├── <ComponentName>.story.ts # Story 定义(声明 props 变体供 gallery 渲染)
└── <ComponentName>.ct.spec.ts # Playwright CT 截图测试(视觉回归)
文件工具职责运行命令
*.spec.tsVitest + jsdom逻辑回归:纯函数、emit、props 渲染、边界pnpm test:unit
*.story.tsGallery声明组件 props 变体被 *.ct.spec.ts 引用
*.ct.spec.tsPlaywright + Gallery视觉回归:像素级截图对比`pnpm test:ct[:dev\:update]`
文件名后缀做了隔离:*.spec.ts 归 Vitest,*.ct.spec.ts 归 Playwright,*.story.ts 归 Gallery,互不冲突。

二·五、新增组件端到端清单(通用步骤)

为任意 <ComponentName> 跑通整条闭环,按序执行(细节仍在各阶段 references,此处只给时序导航):

  1. 填 Part A(开发前):按 references/component-readme-template.md 产出 §1~§7,重点补齐「能力维度矩阵」(防漏功能)与「不变量红线」(防假绿),评审通过再写代码(§七铁律)。详见 §十 测试完备性方法论。
  2. 写组件:<ComponentName>.vue(薄壳 + emit)+ 必要的 <ComponentName>.logic.ts(纯函数 / use*.ts Hook)。关注点分离见 §五。
  3. 写 Vitest:<ComponentName>.spec.ts,Mock 用别名导入(§三 / references/vitest-strategy.md),pnpm test:unit 全绿。
  4. 写 Story:<ComponentName>.story.ts 声明 props 变体,ct/stories.ts 显式静态导入(§四 / references/ct-gallery.md §三)。
  5. 手动视觉迭代:pnpm ct:server 开画廊,HMR 反复调;?story=<ComponentName>/<Variant> 深链或侧栏浏览。
  6. 写 CT 截图:<ComponentName>.ct.spec.ts 用 ?story= 一步挂载 + 等稳定后截图(§四 / references/ct-gallery.md §四~§五)。
  7. 锁基线:pnpm test:ct:dev 确认 → pnpm test:ct:update 确立基线;之后 pnpm test:ct 回归。
  8. 类人验证:按 README §4/§10 验证流程逐项点击(脚本或 MCP,§八 / references/mcp-playwright.md),输出 PASS/FAIL 并截图。
  9. 沉淀 Part B(开发中/后):§8~§12 随闭环补全(§七)。
常见坑排查表
现象根因处置
Gallery / CT 里组件空白或显示原始值组件内用相对路径导入被 mock 的模块,绕过别名桩打到真实后端改为项目别名导入(§三 / references/vitest-strategy.md §二)
CT 基线频繁抖动失败截图前未等 transition 收尾waitForSelector → waitForFunction(visibility==visible) → waitForTimeout(400)(§四 / §八)
侧栏污染 CT 基线CT 未带 ?story=CT 永远带 ?story= 深链(§四)
改逻辑后 UI 测试要跟着改逻辑写在 <script setup> 里抽到 *.logic.ts 纯函数(§五)
本机 CT 命令失败缺对应浏览器 / channel 不符playwright install <browser> 并校验配置 channel(§六)

三、阶段一:Vitest 逻辑回归

要点:纯函数输入输出、组件 emit 触发、props 渲染、边界条件(空数据 / 加载中 / 错误态)。

  • 运行 / Mock 策略 / mount 步骤 / 别名优先纪律 → 详见 references/vitest-strategy.md
  • 关键纪律:组件内部凡涉及被 mock 的模块,必须用项目别名导入,不要用相对路径(相对路径会绕过 Vite 别名桩,在 Gallery / CT 里打到真实后端,导致组件空白或返回原始值)。

四、阶段二:Playwright CT 截图验证

架构:自建 Gallery 模式(轻量 Storybook 替代),而非官方 CT 包。预览与测试共用同一套 story / 同一份 Vite 配置,所见即所测。

  • Gallery 架构、开发循环命令(ct:server / ?story= 深链 / 侧栏)、Story 编写、CT 测试编写(?story= 一步挂载 + 稳定后再截图纪律)、为何不用 Puppeteer 兜底 → 详见 references/ct-gallery.md
?story=<id> 是 URL 查询参数,不是 server CLI 参数;CT 永远带 ?story=,因此侧栏不会污染 CT 基线。

五、关注点分离(核心)

不把逻辑放进组件,测试就会变得困难。 如果 <script setup> 里直接写了 fetch()、new Date()、复杂 filter/map、拼装数据,Vitest 就需要 mock 更多东西,且逻辑与 UI 耦合,改逻辑时测试也得改。

❌ 反模式:组件内嵌逻辑
──────────────────────────────────────
const formatted = computed(() => props.data.map(it => ({
...it, statusText: it.status === 'active' ? '启用' : '禁用'
})))
✅ 正确模式:抽到 *.logic.ts
──────────────────────────────────────
// user.logic.ts ── 纯函数,极易测试
export function formatList(data: T[], dict: Record<number, string>) {
return data.map(it => ({ ...it, statusText: dict[it.status] ?? '未知' }));
}
// index.vue ── 只负责渲染
const formatted = computed(() => formatList(props.data, statusDict));
代码位置测试工具测什么
*.logic.ts 纯函数Vitest输入输出、边界、异常
*.vue templateVitestprops 渲染、emit 事件
*.vue 样式/布局Playwright CT截图对比

六、命令速查

bash
# 在 <web-root> 下执行
# === 开发循环(视觉快速迭代)===
pnpm ct:server # 手动浏览器预览(HMR;无参数=侧栏,?story=单故事)
pnpm test:ct:dev # 有头截图存档(不对比,开发中确认用)
# === Vitest 逻辑回归 ===
pnpm test:unit # 全部 Vitest 测试
pnpm exec vitest run --config vitest.config.unit.ts path/to/xxx.spec.ts # 单文件
# === CT 截图回归 ===
pnpm test:ct # 无头模式,截图对比基线
pnpm test:ct:update # 更新基线截图(确认效果后)
前置依赖:CT 命令依赖本机浏览器(通常 channel: 'chrome' 或项目配置的浏览器)。本机无对应浏览器时这些命令会失败;CI 中按需改为 playwright install <browser> 并调整配置 channel。
CI 与基线管理要点
  • CI 跑 CT:CT 依赖本机浏览器,CI 中需先 playwright install <browser> 并确认配置 channel 与安装的浏览器一致;基线对比失败应阻断合并。
  • 基线管理:基线截图是"视觉契约",更新需人工 review(PR 里贴 before/after 或走预览 review),避免无意识覆盖;基线漂移时回滚到上一版快照即可。
  • 产物存档:test-results/ 与 ct/verify-shots/ 均为瞬态,CI 仅保留失败时的产物供排查,常态不提交。

七、组件 README 模板(开发前必填 + 闭环沉淀)

每个组件目录(core/components/<Name>/)都应有一份 README.md,作为「设计 ↔ 功能 ↔ Story ↔ 测试 ↔ 验证」的唯一事实源。完整模板见 `references/component-readme-template.md`。

铁律:开始编码前必须先填 Part A(开发前必填)并经评审,再动手写 `.vue`。 Part A 是验收标准与后续验证的输入,避免"边写边想、需求不清"导致返工。

Part A — 开发前必填(动手前产出)

  1. 功能需求(FR):角色 / 功能 / 价值,每条可验收
  2. 能力维度矩阵(Completeness Matrix):枚举维度画矩阵,每个可达格 = 必实现且必测的能力(防漏功能,详见 §十)
  3. 设计:定位、分层契约、交互模式、视觉要点
  4. 流程:用户操作流程、关键数据流、状态机
  5. 功能验证列表(Verification Checklist / 故事清单):源于 FR,逐条可勾选,是完成定义也是类人验证输入(= 最终走查闸门)
  6. 不变量红线(Invariants):开发前列出"容易破、破了用户立刻可见"的负向约束,每条必有守卫测试(防假绿,详见 §十)
  7. 数据契约:依赖接口、字段与枚举映射、Mock 约定(确保不请求真实后端)
  8. 边界与异常:空 / 加载 / 错误 / 分页边界 / 超长 / 超大列表
  9. 待确认项(Open Questions):开发前清零

Part B — 开发中 / 后沉淀(闭环产出)

  1. 功能 ↔ Story ↔ 测试 对应表(迭代导航图)
  2. 视觉基线说明(哪些状态需锁 CT 基线)
  3. 验证流程(类人点击清单,复用 §4)
  4. 问题原因分析(仅 BUG 修复)
  5. 变更记录(Changelog)
该 README 把"人肉确认"固化为可复跑的验证清单(§4 + §10),并让"改代码→看 Vitest→按 Story 看视觉→CT 锁基线"的导航图始终成立。

八、类人点击验证流程(真人式点击,补 CT 之不足)

自动化 CT(*.ct.spec.ts)是像素级比对:布局没变就过,但它只证明"长这样",不证明"点得动、数据对"。为此在闭环末尾加一道类人点击验证——启动 ct:server 后用 Playwright 按组件 README 的「验证流程」逐项点击、翻页、断言文字与勾选数,输出每功能 PASS/FAIL 报告并截图,等价于一个人在浏览器里逐一确认功能真的可用。

两种执行方式:

  1. 脚本方式:按 README「验证流程」表编写一个 Playwright 脚本,逐项 click / 翻页 / toHaveText / toHaveCount 断言 + 截图。确定性高、可 CI,不需额外依赖;
  2. 带 MCP Playwright 的智能体(子代理 / 专家):用 @playwright/mcp 工具直接驱动浏览器,并能读取截图做视觉核对,更灵活(注册与操作清单见 references/mcp-playwright.md)。
无论哪种方式,都复用同一套 ?story= 深链 + ct/mocks/ 数据,环境一致,不会"演示页和真实组件两套实现"。

纪律(与 CT 共用):

  • 等挂载稳定:waitForSelector → waitForFunction(visibility==visible) → waitForTimeout(400),避免动画抖动误判;
  • 断言用文字而非像素:类人验证的价值正是确认"数据对",优先 toHaveText / toHaveCount;
  • 选择器型组件不自动开弹窗:需显式点击展开 / 点按钮开弹窗,以验证中间态。

十、测试完备性方法论(理论指导:防漏功能 + 防假绿)

深度展开见 references/testing-completeness-methodology.md。本技能之所以能"不漏功能、测试测得出问题、按故事逐一验收",靠的是把成熟测试理论落到 README 三块载体 + 四阶段流程。

为什么需要它:组件开发两类典型失败——① 漏功能(只做单选忘多选、列表回显显示数字);② 假绿(所有测试全绿但线上有 bug)。两者都靠下面三块消除。

README 三大理论载体(开发前必填)

  1. 能力维度矩阵(Completeness Matrix)——枚举"形态 × 来源 × 状态 × 数据态 × 交互"等维度画矩阵,每个可达格 = 一个必须实现且测试的能力;空白格 = 漏了或不支持。→ 防漏功能。
  2. 不变量红线(Invariants)——开发前列出"容易破、破了用户立刻可见"的负向约束(expect 绝不允许…),每条必有守卫断言测试。→ 防假绿。
  3. 故事清单(§4 验证列表)——每个故事 = ?story= 深链 + 操作步骤 + 期望;开发完按此逐项走查全 PASS 才算完成。→ 最终交付闸门。

四阶段流程:Phase 0 写 README(矩阵+不变量+故事)→ Phase 1 派测试(故事→CT 语义断言;不变量→守卫测试;mock 掉的核心逻辑额外生成"真实契约测试+桩忠实性测试"双测)→ Phase 2 实现(红转绿、逻辑抽 *.logic.ts、别名导入)→ Phase 3 故事走查闸门(全 PASS 交付)。

防假绿纪律(本会话真实教训):① 截图只锁视觉不锁语义,用户可见文本必用 toContainText 断言;② 绝不在缺陷态更新截图基线(否则固化 bug);③ mock 掉核心逻辑必须"真实模块契约测试 + 桩忠实性测试"双测,缺一即掩盖缺陷;④ 测试须先确认"能因正确原因变红"。

真实案例:LovSelect 曾"LIST 回显显示数字"而所有测试全绿,正是四层原因全中(桩不忠实 / 只截图 / 单测 mock 掉核心逻辑 / 缺语义断言)。修复后补的双测即本方法论落地,见 core/components/LovSelect/README.md Part C。

十一、参考文档

文档内容
references/ct-environment-setup.mdCT 环境从零搭建(目录/配置文件/脚本/gitignore/纪律,新项目复刻)
references/vitest-strategy.mdVitest Mock 策略、mount 步骤、别名优先纪律
references/ct-gallery.mdGallery 架构、开发循环命令、Story / CT 编写、Puppeteer 废弃
references/mcp-playwright.mdMCP Playwright 注册(按环境配置)、操作清单、读截图核对
references/component-readme-template.md组件 README 模板(Part A 开发前必填 + Part B 闭环沉淀)
references/testing-completeness-methodology.md测试完备性方法论(理论根基 / 矩阵 / 不变量 / 四阶段流程 / 防假绿纪律 / 真实案例)
docs/standards/testing-standard.md测试分层、Mock 策略、覆盖率门槛、CT 架构
docs/standards/frontend-testable-development.md团队规范总纲
<web-root>/AGENTS.md硬约束(关注点分离、测试策略、命名约定)

Security

  • Security scanPassed, 95 of 100Pattern checks on the skill's files.
  • Model reviewPassed

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

7-day trend score
0

Not refreshed yet.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/newlifex/newlife.cube/vue-component-visual-loop/badge)](https://verified-skill.com/skills/newlifex/newlife.cube/vue-component-visual-loop)

Something wrong with this skill or its page? Tell us.