← ClaudeAtlas

frontend-best-practiceslisted

写 React/Vue 前端代码时使用。组件、状态、性能、可访问性的实战规范。
Wade-DevCode/awesome-coding-skills-cn · ★ 3 · Web & Frontend · score 78
Install: claude install-skill Wade-DevCode/awesome-coding-skills-cn
# 前端最佳实践 ## 何时用 - 新建或拆分 React/Vue 组件时,动手前先对照核心规则过一遍。 - 发现某个组件既负责数据请求、又负责渲染逻辑、又管着多层子组件的状态时。 - 遇到页面交互卡顿、控制台出现"re-render 过多"警告,需要排查性能问题时。 - 准备提交包含新组件或重构现有组件的 PR,做最终自查时。 ## 核心规则 ### 1. 组件单一职责 **规则:** 一个组件只做一件事——要么负责展示,要么负责业务逻辑,要么负责布局;三者不要混在一起。单个组件文件超过 200 行就该警惕,超过 300 行必须拆分。 **为什么:** AI 倾向于把所有逻辑塞进一个"万能组件":在同一个 `UserDashboard` 里既发接口请求、又做权限判断、又渲染三种不同的卡片、还内联着分页逻辑。这种组件无法独立测试,改一处牵连四处,新成员光是读懂就要半小时。 **怎么做:** - 拆分时按职责划分:`useUserData`(数据层)、`UserCard`(展示层)、`UserDashboard`(组装层)各司其职。 - 遇到"这个组件到底在做什么"需要超过一句话解释的,就是该拆的信号。 - 展示组件只接收 props、不持有业务状态、不调接口,可以用纯函数组件写。 --- ### 2. 状态就近放置 **规则:** 状态只提升到真正需要它的最近公共祖先,不默认丢进全局 store 或顶层组件。 **为什么:** AI 常犯的毛病:把一个弹窗的 `isOpen` 状态放进 Redux/Pinia,然后在四个不相关的地方订阅它;或者把一个表单的草稿数据提升到根组件,导致全页面每次输入都重渲染。全局化看起来"方便统一管理",实则制造了隐式耦合,状态变更的影响范围变得不可预测。 **怎么做:** - 先问:「只有这一个组件用这个状态吗?」——是,就放在组件内部。 - 「父子两个组件都用?」——提升到它们的最近公共父组件。 - 只有跨路由、跨页面确实需要共享时,才引入全局状态管理。 - prop drilling 超过两层才考虑 Context/Provide-Inject,不要一遇到跨层就上全局 store。 --- ### 3. 避免无谓重渲染 **规则:** 传给子组件的对象和函数必须保持稳定引用;不在渲染函数体内直接创建新对象、新数组或新函数作为 prop 传下去。 **为什么:** AI 生成的代码里最常见的性能坑:在父组件渲染函数里写 `style={{ color: 'red' }}` 或 `onClick={() => handleClick(id)}`。每次父组件重渲染都会生成新的对象/函数引用,即使值没变,子组件(尤其是用 `React.memo` 或 Vue 响应式包裹的)也会被迫重渲染,列表里有几十个子组件时帧率肉眼可见地掉。 **怎么做:** - React:用 `useMemo` 缓存计算结果和对象字面量,用 `useCallback` 缓存事件处理函数,对纯展示子组件用 `React.memo` 包裹。 - Vue:把衍生数据写成 `computed`,不要在 `<template>` 里内联方法调用返回新对象。 - 性能优化应有性能数据支撑,不要对每个变量无脑加 `useMemo`——有缓存本身也有开销。 --- ### 4. 副作用收口 **规则:** 数据请求、事件订阅、定时器等副作用必须放进受控的 effect 中,并在清理函数里正确取消,不允许裸写在组件顶层或渲