本节摘要:当多个组件共用一段逻辑,就要决定"用哪种抽象抽走它"。高阶组件(HOC)、混入(Mixins)、自定义 Hook、组合式函数四套方案解决同一问题,却在可读性、来源可追溯、作用域隔离上高下立判。本节回到"比稿现场",把四套方案逐场评审,给出新时代的倾向。
本节阅读目标
阅读完本节,你应当能够:
"我想让多个组件共享一段逻辑"。
高阶组件(Higher-Order Component):一个函数,接收一个组件,返回一个被装饰过的组件。React 传统方案。
function withLogging(Wrapped) { return function (props) { return <Wrapped {...props} />; }; }
混入(Mixins):把一组选项/数据合并注入组件,Vue 2 时代常用,Vue 3 已倾向弃用。
const loggerMixin = { methods: { log(msg) { console.log(msg); } }, };
自定义 Hook:React 以 use 开头的函数,把状态与副作用抽成可复用单元。
function useCounter() { const [count, setCount] = useState(0); const inc = () => setCount((c) => c + 1); return { count, inc }; }
组合式函数:Vue Composition API 里以 use 开头的函数,把响应式逻辑抽走。
function useCounter() { const count = ref(0); const inc = () => { count.value += 1; }; return { count, inc }; }
前两个更像"装饰/合并",后两个更像"组合/函数化"。这条演化线的终点是:把状态与逻辑组织成可复用的函数。
结论在 React 与 Vue 各自社区已经成为共识:现代工程几乎都用自定义 Hook / 组合式函数,HOC 留给历史或特定封装,混入基本弃用(Vue 3 也退出主推)。
| 方案 | 框架 | 形式 | 可追溯 | 现状 |
|---|---|---|---|---|
| HOC | React | 包装组件 | 中 | 旧代码常见 |
| 混入 Mixins | Vue2 历史 | 合并选项 | 低 | 已倾向弃用 |
| 自定义 Hook | React | use 开头函数 | 高 | 推荐 |
| 组合式函数 | Vue | 组合函数 | 高 | 推荐 |

当评审"这段通用上传逻辑怎么复用"时,把四套方案摆上桌:HOC 会让组件嵌套加深、混入来源不明,而自定义 Hook / 组合式函数把状态和动作封进一个可读函数,来源一目了然、还能组合。用"能读、能查、能组合"三个词打分,Hook / 组合式函数以绝对优势胜出。这套表达,正是"比稿现场"要训练的判断力。
比稿不能停在口号,落到代码才见真章。假设要在一块通用逻辑里维护"上传进度百分比"。用自定义 Hook 的写法是:
function useUpload() { const [progress, setProgress] = useState(0); const start = () => setInterval(() => setProgress((p) => Math.min(p + 10, 100)), 300); return { progress, start }; }
组件里一行引进来用,进度是谁的样子、谁在变,函数名 + setter 一目了然,还能被别的 Hook 自由组合。这是"组合函数"的典型面目:像一个普通函数,但内部携带状态与副作用,源代码直接可查。
相对的,若用混入实现同一件事,progress 和 start 会从某个匿名 mixin 悄悄注入组件,新旧值对比、优先级冲突都在代码外发生——你读组件时根本无从判断"这个 progress 从哪来"。"来源可追溯"四字差异,才是后者在比稿里被淘汰的根因:功能都能做,但可维护性决定了谁配活到版本二。这条判断,是所有复用抽象评审里最该被记住的一句话。
复用抽象用得好是省力杠杆,但每个抽出来的"复用单元"本身也要被人读懂、被后续维护,这份成本就是抽象欠下的债。判断一份逻辑要不要抽,可以把你的目标折射成两问:这段代码真的有第二个使用方吗?抽出来后,使用者是不是明显比复制粘贴更省心?两问都答"是",抽象就是正收益;否则它就是为假设中的复用提前付费。回到比稿现场那句话——能读、能查、能组合,永远比"招式多"更值钱。
组件之间的协作与复用这一章画上句号。下一章我们把视角拉远到整个应用:状态管理与路由导航,解决"多个页面共享状态、页面之间如何导航 以及 如何异步取数"这三大工程题。