Appearance
组合式API
什么是组合式 API?
组合式 API (Composition API) 是一系列 API 的集合,使我们可以使用函数而不是声明选项的方式书写 Vue 组件。它是一个概括性的术语,涵盖了以下方面的 API:
响应式 API:例如
ref()和reactive(),使我们可以直接创建响应式状态、计算属性和侦听器。生命周期钩子:例如
onMounted()和onUnmounted(),使我们可以在组件各个生命周期阶段添加逻辑。依赖注入:例如
provide()和inject(),使我们可以在使用响应式 API 时,利用 Vue 的依赖注入系统。
组合式 API 是 Vue 3 及 Vue 2.7 的内置功能。对于更老的 Vue 2 版本,可以使用官方维护的插件 @vue/composition-api。在 Vue 3 中,组合式 API 基本上都会配合 <script setup> 语法在单文件组件中使用。下面是一个使用组合式 API 的组件示例:
vue
<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>虽然这套 API 的风格是基于函数的组合,但组合式 API 并不是函数式编程。组合式 API 是以 Vue 中数据可变的、细粒度的响应性系统为基础的,而函数式编程通常强调数据不可变。
为什么要有组合式 API?
更好的逻辑复用
组合式 API 最基本的优势是它使我们能够通过组合函数来实现更加简洁高效的逻辑复用。在选项式 API 中我们主要的逻辑复用机制是 mixins,而组合式 API 解决了 mixins 的所有缺陷。
更灵活的代码组织
许多人喜欢选项式 API 的原因是它在默认情况下就能够让人写出有组织的代码:大部分代码都自然地被放进了对应的选项里。然而,选项式 API 在单个组件的逻辑复杂到一定程度时,会面临一些无法忽视的限制。这些限制主要体现在需要处理多个逻辑关注点的组件中,这是我们在许多 Vue 2 的实际案例中所观察到的。
从左面的图中可以看到,处理相同逻辑关注点的代码被强制拆分在了不同的选项中,位于文件的不同部分。在一个几百行的大组件中,要读懂代码中的一个逻辑关注点,需要在文件中反复上下滚动,这并不理想。另外,如果我们想要将一个逻辑关注点抽取重构到一个可复用的工具函数中,需要从文件的多个不同部分找到所需的正确片段。
而如果用 组合式 API 重构这个组件,将会变成下面右边这样:

现在与同一个逻辑关注点相关的代码被归为了一组:我们无需再为了一个逻辑关注点在不同的选项块间来回滚动切换。此外,我们现在可以很轻松地将这一组代码移动到一个外部文件中,不再需要为了抽象而重新组织代码,大大降低了重构成本,这在长期维护的大型项目中非常关键。
更好的类型推导
组合式 API 主要利用基本的变量和函数,它们本身就是类型友好的。用组合式 API 重写的代码可以享受到完整的类型推导,不需要书写太多类型标注。
更小的生产包体积
搭配 <script setup> 使用组合式 API 比等价情况下的选项式 API 更高效,对代码压缩也更友好。这是由于 <script setup> 形式书写的组件模板被编译为了一个内联函数,和 <script setup> 中的代码位于同一作用域。不像选项式 API 需要依赖 this 上下文对象访问属性,被编译的模板可以直接访问 <script setup> 中定义的变量,无需从实例中代理。这对代码压缩更友好,因为本地变量的名字可以被压缩,但对象的属性名则不能。