Vue 3 的组合式 API优点
Vue 3 的组合式 API 相比选项式 API 的核心优势在于逻辑复用性和代码组织方式。下面通过一个具体示例说明为什么它更灵活、更逻辑化:
场景需求
假设我们需要在组件中实现:
- 跟踪鼠标位置
- 计数器功能
- 窗口尺寸变化监听
选项式 API 实现 (Vue 2 风格)
export default {
data() {
return {
x: 0,
y: 0,
count: 0,
windowWidth: 0
}
},
methods: {
updateMouse(e) {
this.x = e.pageX
this.y = e.pageY
},
increment() {
this.count++
},
updateWindowSize() {
this.windowWidth = window.innerWidth
}
},
mounted() {
window.addEventListener('mousemove', this.updateMouse)
window.addEventListener('resize', this.updateWindowSize)
this.updateWindowSize()
},
beforeUnmount() {
window.removeEventListener('mousemove', this.updateMouse)
window.removeEventListener('resize', this.updateWindowSize)
}
}
问题分析:
- 逻辑碎片化:鼠标跟踪、计数器和窗口尺寸的逻辑分散在
data、methods和生命周期钩子中 - 复用困难:无法直接复用鼠标跟踪或窗口监听逻辑
- 代码膨胀:当功能增加时,组件会变得臃肿难维护
组合式 API 实现 (Vue 3 风格)
import { ref, onMounted, onBeforeUnmount } from 'vue'
// 1. 鼠标位置逻辑(可复用的组合函数)
function useMouse() {
const x = ref(0)
const y = ref(0)
const update = e => {
x.value = e.pageX
y.value = e.pageY
}
onMounted(() => window.addEventListener('mousemove', update))
onBeforeUnmount(() => window.removeEventListener('mousemove', update))
return { x, y }
}
// 2. 窗口尺寸逻辑(可复用的组合函数)
function useWindowSize() {
const width = ref(window.innerWidth)
const update = () => width.value = window.innerWidth
onMounted(() => window.addEventListener('resize', update))
onBeforeUnmount(() => window.removeEventListener('resize', update))
return { width }
}
// 3. 组件中组合这些功能
export default {
setup() {
const count = ref(0)
const { x, y } = useMouse()
const { width } = useWindowSize()
const increment = () => count.value++
return {
count,
increment,
x,
y,
width
}
}
}
组合式 API 的优势解析:
1. 逻辑关注点分离
- 传统方式:相同功能的代码分散在不同选项块中(
data+methods+lifecycle hooks) - 组合式:将鼠标跟踪、窗口尺寸等独立逻辑封装成自包含函数,组件只需组合这些函数
2. 真正的逻辑复用
- 创建
useMouse()和useWindowSize()等可复用逻辑单元 - 在任何组件中只需一行代码即可引入完整功能:
// 在其他组件复用 import useMouse from '@/composables/useMouse' export default { setup() { const { x, y } = useMouse() // ... } }
3. 更灵活的代码组织
- 按功能逻辑而非选项类型组织代码
- 新增功能时只需添加新的组合函数,不破坏现有结构
- 删除功能时直接移除对应的组合函数调用
4. 更好的类型推导
- 组合函数天然支持 TypeScript 类型推导
- 选项式 API 的
this上下文导致类型推导困难
5. 逻辑解耦
- 每个组合函数都是独立单元,不依赖组件上下文
- 方便单独测试:
useMouse()的逻辑可脱离组件测试
对比总结
| 维度 | 选项式 API | 组合式 API |
|---|---|---|
| 代码组织 | 按选项类型分散 | 按功能逻辑集中 |
| 复用性 | mixins/作用域插槽 | 直接函数调用 |
| 可读性 | 需在不同区块跳转阅读 | 同一功能代码集中在一起 |
| 复杂度 | 大组件难维护 | 通过组合函数保持简洁 |
| TS支持 | 有限 | 完整类型支持 |
关键理解:组合式 API 不是简单的把代码移到
setup()里,而是通过组合函数(composables)实现原子化逻辑封装,这才是"组合式"的核心含义。
实际开发中,你可以:
- 将通用逻辑提取到
composables目录 - 复杂组件拆分为多个组合函数
- 使用社区成熟组合库(如 VueUse)
这种模式特别适合中大型项目,随着功能增加,优势会愈加明显。