Composition API FAQ
本教程共 40 篇 · 第 40 篇 · 更新于 2026-07-29 · 约 7 分钟阅读
40. Composition API FAQ
本节目标:回答关于 Composition API 最常见的困惑——它跟 Options API 什么关系,跟 React Hooks 有什么区别。
Composition API 是什么
Composition API 是一组允许你用”导入函数的方式”编写 Vue 组件的 API,而不是声明选项。
它包含三个部分:
| 类别 | 包含 | 作用 |
|---|---|---|
| 响应式 API | ref()、reactive()、computed() | 创建响应式状态 |
| 生命周期钩子 | onMounted()、onUnmounted() | 程序化挂载生命周期 |
| 依赖注入 | provide()、inject() | 配合响应式 API 使用 DI |
一个典型的 Composition API 组件:
<script setup>
import { ref, onMounted } from 'vue'
const count = ref(0)
function increment() {
count.value++
}
onMounted(() => {
console.log(`初始值为 ${count.value}`)
})
</script>
<template>
<button @click="increment">{{ count }}</button>
</template>
NoteComposition API 不是函数式编程。它基于 Vue 的可变响应式范式,函数式编程强调不可变性——两者是不同方向。
为什么要用 Composition API
1. 更好的逻辑复用
Options API 里复用的是 mixins。mixins 有三个老大难问题:
- 来源模糊:组件里多了个属性,不知道来自哪个 mixin
- 命名冲突:两个 mixin 都加了
methods.handleClick,打架 - 隐式耦合:多个 mixin 之间靠共享属性通信,改一个可能炸一片
组合式函数完全解决了这三个问题:解构能看到来源、变量名能改、依赖通过参数传递。
2. 更灵活的代码组织
Options API 里,同一功能的代码被拆分到 data、methods、computed、mounted 等不同选项里。看一个逻辑要上下反复跳。
Composition API 让你按逻辑组织代码,相关的状态、计算、方法都放在一起。
3. 更好的 TypeScript 支持
Options API 的设计早于 TS,类型推断需要很复杂的”体操”才能跑通。Composition API 用的是普通变量和函数,天然支持类型推断。
4. 更小的打包体积
<script setup> 编译后的代码可以直接访问作用域里的变量,不需要 this 代理。变量名还能被 minifier 安全缩短。
与 Options API 的关系
能覆盖所有场景吗?
有状态逻辑——能。用了 Composition API 后,Options 里通常只剩 props、emits、name、inheritAttrs。
TipVue 3.3+ 可以在
<script setup>里用defineOptions设置name和inheritAttrs,连这些都不需要。
两者能混用吗?
能。在 Options API 组件里用 setup() 选项调用 Composition API。
但不推荐新项目这么做。只有在迁移老项目、需要集成 Composition API 写的第三方库时才混用。
Options API 会被废弃吗?
不会。Options API 是 Vue 的核心特性之一,对于中低复杂度项目依然是好选择。Vue 团队没有废弃计划。
与 React Hooks 的对比
Composition API 和 React Hooks 解决同一个问题——逻辑复用。但实现模型不同。
React Hooks 的痛点
React Hooks 每次组件更新都会重新调用:
- 调用顺序敏感:不能把 hook 放在条件里
- 闭包陷阱:hook 里捕获的变量可能是过时的
- 依赖数组:需要手动声明依赖,ESLint 规则经常误报
- useMemo/useCallback:需要手动优化性能
- useRef 管理跨渲染可变值:心智负担
Composition API 的优势
| React Hooks | Vue Composition API |
|---|---|
| 每次更新重新调用 | setup() 只调用一次 |
| 不能条件调用 | 可以条件调用 |
| 手动声明依赖 | 自动追踪依赖 |
| 需要 useCallback 优化子组件更新 | 细粒度响应式,子组件按需更新 |
| useRef 管理可变值 | ref 天然可变 |
| 闭包陷阱 | 没有,因为只调用一次 |
NoteReact 团队也在解决这些问题(比如 React Compiler),但目前仍需要开发者手动处理。Vue 的响应式模型天然绕过了这些坑。
代码对比
React:
function Counter() {
const [count, setCount] = useState(0)
useEffect(() => {
document.title = `Count: ${count}`
}, [count]) // 必须声明依赖
return <button onClick={() => setCount(c => c + 1)}>{count}</button>
}
Vue:
<script setup>
import { ref, watchEffect } from 'vue'
const count = ref(0)
watchEffect(() => {
document.title = `Count: ${count.value}` // 自动追踪
})
</script>
<template>
<button @click="count++">{{ count }}</button>
</template>
Vue 版本少了依赖数组,代码更直观。
什么时候该用 Options API
Options API 不是”落后”的技术。它适合:
- 新手入门,概念更少
- 小型项目,逻辑简单
- 团队成员更熟悉 Options API
- 不需要复杂逻辑复用的场景
本节回顾
- Composition API 通过函数组合实现逻辑复用
- 解决了 Mixins 的来源模糊、命名冲突、隐式耦合问题
- 代码按逻辑组织,TypeScript 支持更好
- Options API 不会被废弃,两者可以混用
- 相比 React Hooks,Composition API 没有闭包陷阱、不需要依赖数组
- 根据项目复杂度和团队偏好选择合适的 API