一句话结论
小页面用 Options,大逻辑用 Composition。
不是什么 "Composition 取代 Options",两个都是 Vue 官方一等公民,选对场景比选对 API 重要。
Options API --- 房间分区清晰
每个功能都有固定格子:data、methods、computed、watch。
vue
<script>
export default {
data() {
return { count: 0 }
},
methods: {
increment() { this.count++ }
},
computed: {
doubled() { return this.count * 2 }
}
}
</script>
🚀 适合:
- 简单页面(表单、弹窗、展示卡片)
- 新人上手、团队习惯 Options
- 组件逻辑 < 100 行
⚠️ 痛点:
一个功能横跨 data / methods / computed 三个格子,复杂组件里改一个功能要上下翻 5 次。
Composition API --- 按逻辑聚合
逻辑相关的代码堆在一起,想拆就拆。
vue
<script setup>
import { ref, computed } from 'vue'
const count = ref(0)
const increment = () => count.value++
const doubled = computed(() => count.value * 2)
</script>
🚀 适合:
- 复杂组件(500+ 行)
- 多组件复用相同逻辑(鼠标跟踪、表单校验、请求状态)
- TypeScript 项目(类型推断天然友好)
💡 面试加分玩法 --- 逻辑抽离:
ts
// useMouseTracker.ts
import { ref, onMounted, onUnmounted } from 'vue'
export function useMouseTracker() {
const x = ref(0)
const y = ref(0)
function update(e: MouseEvent) {
x.value = e.clientX
y.value = e.clientY
}
onMounted(() => window.addEventListener('mousemove', update))
onUnmounted(() => window.removeEventListener('mousemove', update))
return { x, y }
}
vue
<!-- 使用 -->
<script setup>
import { useMouseTracker } from './useMouseTracker'
const { x, y } = useMouseTracker()
</script>
什么时候选哪个?一张表说清楚
| 场景 | 推荐 | 原因 |
|---|---|---|
| 简单表单/弹窗 | Options | 搭得快,不用动脑子 |
| 200+ 行的中型组件 | 都行 | 看团队习惯,别纠结 |
| 500+ 行大型组件 | Composition | 逻辑混在一起改不动了 |
| 跨组件复用逻辑 | Composition | useXxx() 天然可复用 |
| TS 重度项目 | Composition | 类型推导不用写接口 |
| 新人有 Options 基础 | Options | 别为炫技增加学习成本 |
| 新上手的 Vue 新项目 | Composition | 现在是 Vue 主推方向 |
个人实战经验: 我的策略是"混用不混写"。一个组件里两个 API 可以并存 ------ 简单部分用 Options,复杂逻辑用 setup()。Composition 不是必须全盘抛弃 Options。