0%

Vue 的 Composition API 和 Options API

Vue 3 的发布带来了一个重要的新特性——Composition API,它与 Vue 2 经典的 Options API 并存,为开发者提供了更多灵活性。Options API 以“选项”为中心组织代码,而 Composition API 则基于函数式思想,将逻辑按功能聚合。

Options API 回顾

Options API 是 Vue 2 及 Vue 3 中仍然支持的传统写法。它将组件的不同部分(数据、方法、计算属性、侦听器、生命周期钩子)归类到不同的选项(data、methods、computed、watch、created 等)中。

Options API 示例:计数器组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<template>
<div>
<p>Count: {{ count }}</p>
<button @click="increment">+</button>
<button @click="decrement">-</button>
<p>Double: {{ doubleCount }}</p>
</div>
</template>

<script>
export default {
data() {
return {
count: 0
};
},
computed: {
doubleCount() {
return this.count * 2;
}
},
methods: {
increment() {
this.count++;
},
decrement() {
this.count--;
}
},
mounted() {
console.log('组件已挂载,初始值:', this.count);
}
};
</script>

特点

  1. 代码按选项类型(数据、方法、生命周期)自然分割,结构清晰,易于上手。
  2. 对于简单组件,逻辑一目了然。
  3. 但当组件变得复杂时,同一功能的代码可能分散在多个选项中,导致维护困难。

Composition API 介绍

Composition API 是 Vue 3 中新增的一组 API,它允许开发者使用函数(setup 函数)来组织组件逻辑。通过 ref、reactive、computed、watch、生命周期钩子(如 onMounted)等函数,将相关逻辑聚合在一起,并支持提取可复用的逻辑单元(组合式函数)。

Composition API 示例:计数器组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<template>
<div>
<p>Count: {{ count }}</p>
<button @click="increment">+</button>
<button @click="decrement">-</button>
<p>Double: {{ doubleCount }}</p>
</div>
</template>

<script>
import { ref, computed, onMounted } from 'vue';

export default {
setup() {
const count = ref(0);

const doubleCount = computed(() => count.value * 2);

function increment() {
count.value++;
}
function decrement() {
count.value--;
}

onMounted(() => {
console.log('组件已挂载,初始值:', count.value);
});

return {
count,
doubleCount,
increment,
decrement
};
}
};
</script>

特点:

  1. 所有逻辑都集中在 setup 函数内,可以按功能模块分组,而不是按选项类型。
  2. 更容易提取和复用逻辑(使用组合式函数)。
  3. 对 TypeScript 类型推导更友好。

核心区别

逻辑组织方式

  • Options API:按照选项类型强制分组。当组件功能增多时,同一功能的逻辑可能散落在 data、methods、computed 等不同选项中,难以快速理解整体功能。
  • Composition API:允许开发者按照功能模块自由组织代码,可以将相关变量、函数、计算属性写在一起,就像编写普通 JavaScript 函数一样。

代码复用

  • Options API:通常使用 mixins 复用逻辑,但 mixins 存在命名冲突、来源不清晰等缺点。
  • Composition API:通过自定义组合式函数(useXxx)实现逻辑复用,类似于 React Hooks,清晰且无副作用。

TypeScript 支持

  • Options API:虽然可以通过一些技巧实现类型推导,但不够自然,且 this 的上下文让类型推断复杂。
  • Composition API:基于函数和变量,天然支持 TypeScript 类型推导,IDE 提示更友好。

学习曲线

  • Options API:对新手非常友好,概念简单,文档分类清晰。
  • Composition API:需要理解响应式原理(ref、reactive)和 setup 的执行时机,有一定学习成本。

优缺点对比

特性 Options API Composition API
易学性 ⭐⭐⭐⭐⭐ 直观易学 ⭐⭐⭐ 需理解新概念
代码组织 按选项类型分组,简单组件清晰 按功能聚合,复杂组件更易维护
逻辑复用 Mixins(有缺陷) 组合式函数(强大清晰)
TypeScript 支持 一般 优秀
Tree-shaking 选项对象整体引入,不利于摇树 按需引入 API,更利于优化
适用场景 小型组件、新手项目、快速原型 大型项目、复杂组件、需要高度复用的场景

如何选择

  • 如果你是新项目,并且团队成员熟悉 Composition API,推荐使用 Composition API,它更灵活,更适合大型应用。
  • 如果你维护现有 Options API 项目,无需重构,Vue 3 完全兼容 Options API。
  • 对于简单组件,两者皆可,Options API 可能更简洁。
  • 对于需要高度复用逻辑的场景,Composition API 的组合式函数是首选。
  • 如果团队 Vue 2 经验丰富,且项目复杂度不高,继续使用 Options API 也没有问题。
    实际上,Vue 3 允许两种 API 混用,你可以在一个组件中同时使用 setup 和传统选项,但通常不建议这样做,以免造成混乱。

进阶对比:逻辑提取示例

假设我们需要在多个组件中复用鼠标追踪功能。

Options API 使用 mixin

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// mouseMixin.js
export default {
data() {
return { x: 0, y: 0 };
},
mounted() {
window.addEventListener('mousemove', this.update);
},
beforeUnmount() {
window.removeEventListener('mousemove', this.update);
},
methods: {
update(e) {
this.x = e.pageX;
this.y = e.pageY;
}
}
};

使用 mixin 的组件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<script>
import mouseMixin from './mouseMixin';
export default {
mixins: [mouseMixin],
mounted() {
console.log('鼠标位置:', this.x, this.y);
}
};
</script>
Composition API 使用组合式函数
js
// useMouse.js
import { ref, onMounted, onUnmounted } from 'vue';

export function useMouse() {
const x = ref(0);
const y = ref(0);

function update(e) {
x.value = e.pageX;
y.value = e.pageY;
}

onMounted(() => window.addEventListener('mousemove', update));
onUnmounted(() => window.removeEventListener('mousemove', update));

return { x, y };
}

使用组合式函数的组件:

1
2
3
4
5
6
7
8
9
10
<script>
import { useMouse } from './useMouse';
export default {
setup() {
const { x, y } = useMouse();
// 可以直接使用 x, y
return { x, y };
}
};
</script>

对比可见,组合式函数更加清晰,没有隐藏的依赖,且返回值明确。

总结

Options API 和 Composition API 各有千秋。Options API 以其直观的结构赢得了大量 Vue 2 开发者的青睐,而 Composition API 则为复杂应用提供了更好的逻辑组织能力和复用性。Vue 3 同时支持两者,让开发者可以根据项目需求和团队偏好灵活选择。

在实际开发中,建议:

  1. 小型项目或原型:可以使用 Options API 快速搭建。
  2. 中大型项目、组件库、需要长期维护的应用:推荐 Composition API,它更能应对复杂度的增长。
  3. 混合使用也是可行的,但应保持风格一致。
  4. 无论选择哪种 API,Vue 的核心响应式系统和组件化思想始终不变。