Communitygithub.com

deputychinh/frontend

用于在 Vue 3 或 React Web 应用中添加或更改用户可见或可交互的任何内容——屏幕、组件、组合式函数(composable)或 Hook、状态管理、表单、路由或数据获取——即使只是小调整,或当请求只提到“UI”、“页面”、“表单”、“前端”或“按钮没反应”时。

frontend 是什么?

该技能为开发 AI 智能体提供了一套全面的前端开发工作流,适用于 Vue 3 和 React 应用。它强调在编写任何代码之前,先加载仓库约定、检查可复用组件,并为每个视图编写状态表(包括加载、空、错误、成功状态)。智能体被指示先编写失败测试,然后在 feature 文件夹内构建组件,并使用国际化键管理所有可见字符串。该技能还强制要求遵守无障碍标准(WCAG 2.2 AA)、键盘导航,并通过基于 Playwright 和 axe 的端到端测试进行验证。对于 AI 智能体用户而言,它提供了一种结构化、可重复的方法,用于交付健壮、可维护且对用户友好的前端功能。

兼容平台✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/deputychinh/Skills/tree/HEAD/skills/frontend

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

frontend — 为每位用户、每种状态提供可靠的屏幕,并易于修改

先遵循仓库的 CLAUDE.md、docs/conventions.md 和 docs/design-system.md;本技能旨在补充而非覆盖这些文档。视觉工作(设计令牌、布局、颜色、CSS)归属于 css-design;以用户身份运行应用以及最终裁决由 verify-app 负责。

选择技术栈。 Vue 3 和 React 均为一级公民,遵循相同的规则。使用仓库已有的框架;对于新应用,使用交付配置文件中的前端默认值(参见仓库 README),否则在分流阶段询问一次。Vue:TypeScript + Vite (npm create vue@latest -- --ts --router --pinia --vitest --playwright --eslint --prettier),参考 references/vue-patterns.md。React:TypeScript + Vite(或仓库的元框架),参考 references/react-patterns.md。切勿在一个应用中混合使用框架。需要 SSR 或 SSG 来优化 SEO?请在 ADR(architect)中记录 Nuxt 或 Next.js;本技能无论在哪种情况下都涵盖客户端部分。

工作流程

  1. 加载仓库约定和清单。 读取 CLAUDE.md、docs/conventions.md、docs/design-system.md;列出可复用部分(ls src/components src/features src/composables src/hooks src/stores)。检测数据层、路由、表单和国际化库(Vue:grep -E '"(@tanstack/vue-query|pinia|vue-router|vee-validate|vue-i18n)"' package.json;React:grep -E '"(@tanstack/react-query|@tanstack/react-router|react-router|react-hook-form|i18next|react-intl)"' package.json)。切勿添加第二个数据层、路由、状态管理、表单或国际化库。证据: 故事描述中列出已复用的组件、组合式函数/Hook 以及新增的任何内容,并说明原因。
  2. 在编写代码之前编写状态表。 对于每个视图:列出每一块数据及其位置——服务器(查询)、URL(路由参数/搜索)、共享客户端(Pinia store 或 React context 或仓库的 store)、本地(ref / useState)、派生(computed / render 中的 const)、外部(组合式函数或包装浏览器 API 的 useSyncExternalStore)。然后列出四种状态(加载、空、错误、成功)以及每种状态的复制键。证据: 故事中的表格。
  3. 先编写会失败的测试。 Vitest + @testing-library/vue 或 @testing-library/react、userEvent.setup()、按角色和可访问名称进行查询、每个测试一个行为、在服务边界伪造网络(MSW 或仓库在 src/test-utils 中的伪造客户端)。覆盖每种状态、键盘路径和一个负面案例。证据: 运行结果显示因正确原因而失败。
  4. 在 feature 文件夹内构建。 src/features/<name>/services(类型化的 API 调用,无框架)→ composables / hooks(useX 包装 useQuery/useMutation 和一个键工厂)→ components(Name.vue 包含 <script setup lang="ts">,或 Name.tsx)→ 组装它们的路由视图。属性和事件具有类型,无 any,无非空 !,使用 @/ 导入。证据: git diff --stat 显示更改仅限于该 feature 以及预期的共享更改。
  5. 复制和格式化。 所有可见字符串来自本地化文件(vue-i18n 的 useI18n(),或 React 仓库的国际化库或复制模块),每种语言环境具有相同的键;测试强制键的一致性。数字和日期通过国际化格式化器或 Intl。证据: 键一致性测试通过;无硬编码复制,由 lint 强制(@intlify/vue-i18n/no-raw-text;React:react/jsx-no-literals 或国际化插件的规则)——引用 lint 退出代码。
  6. 使用 css-design 设置样式。 仅使用设计令牌,BEM 块名等于组件名,为每种状态设置样式;.vue 样式通过 postcss-html 进行 lint。证据: Stylelint 通过。
  7. 故事(组件库)。 每种状态一个故事,两种主题;Storybook axe 检查通过。证据: 故事测试和 axe 检查通过。
  8. 门控,按退出代码链式执行。 npm run lint && npm run type-check && npm run test:unit -- --run(Vue:vue-tsc --build;React:tsc -b),或 make ci;切勿仅根据 | tail 判断。证据: 退出代码为 0 且覆盖率等于或高于仓库阈值。
  9. 在真实浏览器中针对生产构建进行旅程测试。 npm run build 并提供输出服务(vite preview,或仓库使用的静态服务器)。为主要路径添加或扩展 Playwright 规范,并包含 @axe-core/playwright(标签 wcag2a wcag2aa wcag21aa wcag22aa,严重和关键错误数为 0)。捕获 docs/delivery/<slug>/evidence/<view>-390.png 和 -1280.png,如果应用有暗色主题,还需捕获暗色主题截图。在引用每张截图前先打开它。证据: 规范通过,PNG 图片存在。
  10. 键盘和屏幕阅读器通过。 使用 Tab 键浏览新视图:顺序、可见焦点、Escape 关闭覆盖层且焦点返回到触发元素;导航后焦点落在新标题上且标题已更改。使用屏幕阅读器(VoiceOver Cmd+F5,或 NVDA)抽查名称和公告。证据: 故事 QA 部分中的三行注释。
  11. 移交。 运行 verify-app 进行端到端验证;在 deliver-loop 中,独立审查对项目进行评分。此处不再重复其步骤。

核心检查清单

  1. 不存储可以派生的内容:使用 computed(React:render 中的 const);不编写仅用于设置其他状态的 watcher 或 effect。
  2. Watcher 和 effect 仅用于与外部同步(DOM API、订阅、定时器、第三方小部件)并在完成后清理(onWatcherCleanup/onUnmounted;React:effect 的返回函数)。由用户操作引起的工作应在事件处理程序中运行。
  3. 服务器数据从不复制到本地状态或 store 中;查询键包含获取数据时使用的每个输入(在 Vue 中作为 ref 或 getter,以便数据变化时重新获取)。
  4. 用户可能分享或重新加载的选择、筛选、标签和分页应位于 URL 查询中。
  5. 每个数据视图都渲染加载、空、错误(带重试)和成功状态;测试覆盖所有四种状态。
  6. 每个输入都有可见的 <label for>(两个框架中均使用 useId() 生成 id);错误通过 aria-describedby 关联文本,保留输入值,提交时焦点移动到第一个无效字段。
  7. 优先使用原生元素(button、a href/路由链接、dialog、details、input type);不使用 div @click / div onClick。
  8. 自定义小部件遵循相应的 WAI-ARIA APG 模式,包括键盘支持。
  9. 不移动焦点的异步结果通过一个 role="status"/role="alert" 区域宣布,该区域仅渲染一次且内容为空(Vue:teleport 到 body;React:portal,如果它必须比视图存活更久)。
  10. 路由变化:更新 document.title 并将焦点移动到页面 h1 或 main(Vue:router.afterEach + 模板引用;React:路由器的等效实现)。
  11. 每个路由和每个有风险的小部件都要捕获错误(Vue:onErrorCaptured 边界组件;React:错误边界)并显示重试,绝不显示空白页面。
  12. 无硬编码显示字符串;每种语言环境具有相同的键。
  13. 测试按角色/标签/文本查询,使用 user-event 交互,并且从不断言类名、组件内部(wrapper.vm、状态值)或组合式函数/Hook 调用。
  14. 无 v-html / dangerouslySetInnerHTML,除非在使用前立即用 DOMPurify 进行消毒;来自数据的 URL 被列入白名单为 https:/mailto:/相对路径。
  15. 仅在存在性能分析测量或记录的需求时才使用 shallowRef/markRaw/v-memo/KeepAlive(React:memo/useMemo/useCallback)。
  16. 图表和数据可视化具有可访问的名称和摘要、数据表(或文本)替代方案、色盲安全调色板(系列之间还可通过标签、形状或图案区分),以及对任何交互的键盘访问——无论仓库使用哪个图表库。

反模式

Vue:

  • watch(items, v => { filtered.value = v.filter(...) })——应使用 computed。
  • const { count } = reactive(state) 或 const { name } = store——会丢失响应性;应使用 toRefs / storeToRefs,或优先使用 ref。
  • watch(props.id, ...) 或将解构后的 prop 传递给组合式函数——应传递 getter () => id。
  • 直接修改 prop 或 useQuery 的数据;直接将查询数据绑定到 v-model——应复制到表单中。
  • 在同一元素上使用 v-if 和 v-for;在可重新排序的列表中使用 :key="index"。
  • 在 onWatcherCleanup 之前或在组合式函数中注册生命周期钩子之前使用 await。
  • 为路由组件使用 defineAsyncComponent(路由直接使用 () => import(...))。
  • 在导航守卫中调用 next()——应返回 false、一个位置或不返回任何内容。
  • 测试深入到 wrapper.vm 或调用 setData。

React:

  • useEffect(() => setFiltered(items.filter(...)), [items])——应在 render 中计算。
  • 当 id 变化时在 effect 中重置表单——应传递 key={id}。
  • Hook 在条件或循环中调用;状态原地修改而非替换。
  • 在可重新排序的列表中使用 key={index};在每次渲染时向记忆化子组件传递新的对象或函数 prop,而该子组件是为了测量的原因而被记忆化的。

两者通用:

  • 挂载时进行没有取消、缓存、重试或错误分支的获取——应使用数据层。
  • 没有空或错误分支的加载动画;错误被吞没到 console.log 中。
  • 对于每天变化的数据,staleTime 保留为 0,导致每次聚焦都重新获取。
  • 没有快照、回滚和 settle 时失效的乐观更新。
  • 使用占位符作为标签;仅用颜色表示错误;role="button" 缺少键盘支持。
  • 到处使用 getByTestId;整个页面的快照;测试实现细节。
  • 功能模块的 barrel 文件将所有内容拉入第一个路由块。
  • :href="user.url" / href={user.url} 未检查协议。

"完成"前的证据

  • 针对每种状态和键盘路径的失败后通过的单元测试。
  • Lint、vue-tsc 或 tsc、测试链式执行,退出代码为 0;覆盖率等于或高于阈值。
  • 针对生产构建的 Playwright 旅程测试,axe 严重/关键错误数为 0。
  • 390 和 1280 像素(以及暗色主题)的截图位于 docs/delivery/<slug>/evidence/,每张都已打开。
  • 故事 QA 部分中的键盘和屏幕阅读器注释。
  • 然后运行 verify-app。

参考资料

  • references/vue-patterns.md — Vue 检查清单:SFC 和组件 API、响应性陷阱、computed vs watch、组合式函数、Pinia、用于 Vue 的 TanStack Query、Vue Router(URL 状态、守卫、焦点)、表单、国际化、无障碍具体实现、性能、安全、工具;每个条目均有来源。
  • references/react-patterns.md — React 检查清单:相同主题,加上静态导出(Next.js / Nuxt generate)变体。
  • references/a11y-and-testing.md — UI 代码的 WCAG 2.2 AA 项、ARIA/APG、键盘和活动区域、图表、用于 Vue 和 React 的 Testing Library、MSW、Playwright + axe、不应测试的内容。

相关技能