一、Options API(选项式 API)------ 传统方式
Options API 是 Vue 2 和 Vue 3 都支持的经典写法。它把一个组件的逻辑拆分成不同的选项,每个选项负责一种类型的逻辑。
1. 常见的选项
data():定义响应式数据。methods:定义方法。computed:定义计算属性。watch:监听数据变化。mounted、created等生命周期钩子。
2. 一个计数器组件示例
js
// Options API
export default {
data() {
return {
count: 0,
message: 'Hello'
};
},
computed: {
doubleCount() {
return this.count * 2;
}
},
methods: {
increment() {
this.count++;
}
},
watch: {
count(newVal) {
console.log(`count 变为 ${newVal}`);
}
},
mounted() {
console.log('组件已挂载');
}
};
3. 它的缺点:逻辑分散
当组件功能变多时(比如一个搜索框同时需要处理输入、防抖、请求、列表展示),相关的代码会散落在 data、methods、watch 等不同选项中。维护时需要在文件里上下翻飞,不好复用也不容易阅读。
二、Composition API(组合式 API)------ 按功能组织代码
Composition API 是 Vue 3 引入的新方案,核心思想是:按功能(或逻辑关注点)来组织代码,而不是按选项类型 。所有逻辑都写在 setup() 函数内(或 <script setup> 块中)。
1. 核心工具
ref():定义基本类型的响应式数据(如数字、字符串),访问和修改需.value。reactive():定义对象类型的响应式数据。computed():计算属性。watch()/watchEffect():监听数据变化。- 生命周期钩子改为了
onMounted、onUpdated等函数,在setup中调用。
2. 同样的计数器,用 Composition API
js
import { ref, computed, watch, onMounted } from 'vue';
export default {
setup() {
// 响应式数据
const count = ref(0);
// 计算属性
const doubleCount = computed(() => count.value * 2);
// 方法
function increment() {
count.value++;
}
// 监听
watch(count, (newVal) => {
console.log(`count 变为 ${newVal}`);
});
// 生命周期
onMounted(() => {
console.log('组件已挂载');
});
// 返回给模板使用
return { count, doubleCount, increment };
}
};
可以发现:与 count 相关的数据、计算属性、方法、监听全部集中在一起,而不是散落各处。
3. 最大优势:逻辑复用(自定义组合函数)
你可以把某一功能的所有逻辑抽离成一个独立的函数,称为 "Composable" (也称 hooks,类似 React hooks 的思想)。
js
// useCounter.js
import { ref, computed } from 'vue';
export function useCounter(initialValue = 0) {
const count = ref(initialValue);
const doubleCount = computed(() => count.value * 2);
function increment() {
count.value++;
}
return { count, doubleCount, increment };
}
在任何组件中都可以直接使用:
js
import { useCounter } from './useCounter.js';
export default {
setup() {
const { count, doubleCount, increment } = useCounter(10);
return { count, doubleCount, increment };
}
};
多个组件共享同一个函数,轻松实现逻辑复用,且代码非常内聚。
三、<script setup> 语法糖 ------ 更简洁
Vue 3 提供了 <script setup> 编译时语法糖,让 Composition API 写起来更接近 Options API 的简洁度,不再需要手动 return。
js
<script setup>
import { ref, computed, watch, onMounted } from 'vue';
const count = ref(0);
const doubleCount = computed(() => count.value * 2);
function increment() {
count.value++;
}
watch(count, (newVal) => {
console.log(`count 变为 ${newVal}`);
});
onMounted(() => {
console.log('组件已挂载');
});
</script>
<template>
<div>
<p>{{ count }} - {{ doubleCount }}</p>
<button @click="increment">+1</button>
</div>
</template>
<script setup> 里定义的变量、函数会自动暴露给模板,是官方现在推荐的写法。
四、Options API vs Composition API 对比
| 对比维度 | Options API | Composition API |
|---|---|---|
| 代码组织 | 按选项类型(data/methods/computed...)分散 | 按功能逻辑聚合 |
| 逻辑复用 | Mixins(易冲突,来源不明) | 自定义组合函数(清晰、无冲突) |
| TypeScript 支持 | 较差,类型推断困难 | 天然友好,函数式写法易于类型标注 |
| 学习曲线 | 直观,新手易上手 | 需要理解 ref、reactive 等概念,略陡 |
| 适用场景 | 小型组件,简单功能 | 复杂组件,需要大量逻辑复用 |
| 官方推荐 | 继续支持,不会废弃 | 推荐用于新项目、大型应用 |