Composition Api 与 Options Api 有什么不同?

1. Vue 2 项目的痛点

可以看到 Options API 代码编写方式:组件状态写在 data 属性上,方法写在 methods 属性上...

用组件的选项(data、computed、methods、watch)组织逻辑在大多数情况下都有效。然而,当组件变得复杂时,对应属性的列表也会增长,这可能会导致组件难以阅读和理解。

2. Options API 缺点

  • 相关业务的代码会被拆散到各个选项里:组件越来越大时,需要不断在 data、methods、computed、watch 之间跳转。
  • 树状结构组织代码,导致逻辑关注点碎片化,阅读时需要反复在多个选项块之间跳转。
  • 复用逻辑通常用 mixin,mixin 多了会引入命名冲突和来源不清的问题。

3. Composition API

在 Vue 3 Composition API 中,组件根据逻辑功能来组织。一个功能所定义的所有 API 会放在一起(更加高内聚、低耦合)。

即使项目很大、功能很多,我们都能快速定位到这个功能所用到的所有 API。

// 同一个功能(用户列表)的代码集中在一起
import { ref, computed, onMounted, watch } from 'vue'
import { fetchUsers } from '@/api/user'

export default {
  setup() {
    // 状态
    const list = ref([])
    const keyword = ref('')
    const filteredList = computed(() =>
      list.value.filter(u => u.name.includes(keyword.value))
    )

    // 方法
    const load = async () => {
      list.value = await fetchUsers()
    }

    // 生命周期
    onMounted(load)

    // 监听
    watch(keyword, () => console.log('keyword changed'))

    return { list, keyword, filteredList, load }
  }
}

4. 对比

逻辑组织

  • Options API:逻辑关注点碎片化,同一个功能分散在多个选项里。
  • Composition API:将某个逻辑关注点相关的代码全部放在一个函数里。

逻辑复用

  • Vue 2:使用 mixin 复用相同逻辑。大量 mixin 混入组件时会造成两个问题:
    • 命名冲突;
    • 多个 mixin 之间的来源不清晰。
  • Vue 3:通过自定义 Hook 函数复用逻辑,函数返回值显式、可读,类型提示友好。

其他方面

  • TypeScript 支持:Composition API + <script setup> 对 TS 的类型推导更友好;Options API 中 this 的类型推导较弱。
  • Tree shaking:Composition API 用到的 API(如 ref、computed)可被独立打包;Options API 把所有选项都暴露在 this 上,tree shaking 不友好。
  • 代码压缩:Composition API 函数形式的代码压缩率更高。

来源整理自:vue3js.cn 面试官系列