组件复用性差,越写越臃肿
很多人一开始写组件图省事,把样式、逻辑、数据请求全堆在一个文件里。比如做个按钮,顺手把点击埋点、权限判断、弹窗逻辑都塞进去,结果这个按钮只能用在某一个页面。换个项目一复制,发现依赖一堆不存在的接口和变量,根本跑不起来。
解决办法是保持组件“单一职责”。按钮就管展示和基础交互,权限控制交给父组件传 props 控制,埋点通过事件回调往外抛。这样下次在别的项目里,直接引用就能用。
父子组件通信混乱
常见的是子组件想改父组件的状态,直接在子组件里调用父级方法,甚至用 $parent 或 context 强行穿透。一旦层级深了,比如 A → B → C → D,D 要通知 A 更新,中间 B 和 C 就成了“传话筒”,代码看起来全是转发逻辑。
更合理的做法是使用事件机制或状态管理工具。比如 Vue 用 emit,React 可以通过回调函数层层上传,或者用 Zustand、Redux 管理全局状态。别为了省两行代码破坏结构清晰度。
样式污染问题频发
写了 .btn { color: red; },结果全项目所有按钮都变红了。这就是典型的全局样式冲突。尤其多人协作时,没人知道谁定义了什么类名。
解决方案很简单:开启 scoped 样式或使用 CSS Modules。Vue 单文件组件加个 scoped 属性,React 推荐用 modules 方式导入:
<style module>\n.btn {\n padding: 8px 16px;\n background: #007acc;\n}</style>编译后类名自动哈希化,避免命名冲突。
组件拆分粒度过细或过粗
有人追求“每个 div 都封装成组件”,结果一个页面 import 二十多个文件,看个结构得翻半天。也有人干脆整个页面写成一个大组件,维护时谁都不敢动。
经验上,能独立复用的 UI 块才拆。比如表单里的地址选择器、头像上传区域,这些在用户中心、发布页都会出现,值得单独抽。而某个页面独有的布局容器,没必要硬拆。
缺乏文档和示例,别人不会用
你辛辛苦苦写了通用下拉框组件,API 设计得很灵活,但同事拿到后不知道怎么传参数,最后自己又写了一个类似的。
建议搭配简单 demo 页面,哪怕只是本地写个测试页。用 Storybook 更好,能直观展示不同 props 下的表现。至少在 README 写清楚支持哪些属性、触发哪些事件。
版本更新导致兼容问题
组件库升级后,某个废弃的 prop 被移除了,下游项目一更新直接报错。尤其是团队内部私有组件库,更新没通知,联调时才发现页面白屏。
发布前做好变更日志(changelog),重大变更标记 BREAKING CHANGE。可以用 semantic-release 配合 conventional commits 自动管理版本号。小范围灰度升级,验证稳定后再推全量。