Vue 3 引入的 Composition API 是一套全新的 API,它的设计初衷是解决 Vue 2 中 Options API 难以重用逻辑和模块化的问题。Composition API 更加灵活,便于代码的逻辑抽离、模块化、复用性强,并且在大型项目中更具优势。它基于函数的编程风格,可以让我们在同一个 setup()
函数内组织组件的各种逻辑。
1. Composition API 的核心概念
1.1 setup
函数
setup
是 Vue 3 组件中使用 Composition API 的入口。在组件实例创建之前执行,它是 Composition API 的核心。在 setup
中,可以定义响应式状态、生命周期钩子、计算属性等。
export default {
setup() {
// 组件逻辑写在这里
return {}; // 返回值将暴露给模板
}
}
1.2 ref
和 reactive
ref
:创建一个可以跟踪单个基本类型数据的响应式对象。当你使用ref
创建一个响应式数据时,Vue 会自动将其包装为对象形式,该对象包含.value
属性来保存数据。
import { ref } from 'vue';
export default {
setup() {
const count = ref(0); // 创建响应式变量
const increment = () => {
count.value++; // 通过 .value 访问和修改
};
return { count, increment };
}
}
reactive
:创建一个响应式对象,适用于复杂的结构,如对象或数组。
import { reactive } from 'vue';
export default {
setup() {
const state = reactive({
count: 0,
user: {
name: 'Alice',
age: 30
}
});
const increment = () => {
state.count++;
};
return { state, increment };
}
}
1.3 computed
计算属性
computed
用于定义计算属性,它的返回值会根据依赖的响应式数据自动更新。
import { ref, computed } from 'vue';
export default {
setup() {
const count = ref(0);
const double = computed(() => count.value * 2);
return { count, double };
}
}
1.4 watch
和 watchEffect
watch
:监听响应式数据的变化,并执行回调函数。常用于异步操作或副作用逻辑。
import { ref, watch } from 'vue';
export default {
setup() {
const count = ref(0);
watch(count, (newValue, oldValue) => {
console.log(`count changed from ${oldValue} to ${newValue}`);
});
return { count };
}
}
watchEffect
:立即执行传入的副作用函数,并自动追踪依赖的响应式数据。
import { ref, watchEffect } from 'vue';
export default {
setup() {
const count = ref(0);
watchEffect(() => {
console.log(`count is now: ${count.value}`);
});
return { count };
}
}
1.5 生命周期钩子
Composition API 提供的生命周期钩子类似于 Options API 中的生命周期钩子,但需要通过函数调用形式使用。
onMounted
:组件挂载完成后触发onUnmounted
:组件销毁前触发onUpdated
:组件更新后触发
import { onMounted, onUnmounted } from 'vue';
export default {
setup() {
onMounted(() => {
console.log('Component has been mounted');
});
onUnmounted(() => {
console.log('Component is about to be destroyed');
});
return {};
}
}
1.6 provide
和 inject
provide
:向下传递数据,使得祖先组件能够将数据提供给后代组件。inject
:接收来自祖先组件通过provide
提供的数据。
// Parent.vue
import { provide, ref } from 'vue';
export default {
setup() {
const message = ref('Hello from Parent');
provide('message', message); // 提供数据
return {};
}
}
// Child.vue
import { inject } from 'vue';
export default {
setup() {
const message = inject('message'); // 注入数据
return { message };
}
}
2. 组合式 API 的实际应用
2.1 创建一个计数器组件
我们可以通过 Composition API 实现一个简单的计数器组件。
<template>
<div>
<p>计数值:{{ count }}</p>
<button @click="increment">增加</button>
</div>
</template>
<script>
import { ref } from 'vue';
export default {
setup() {
const count = ref(0);
const increment = () => count.value++;
return { count, increment };
}
}
</script>
2.2 响应式数据与计算属性
我们可以通过 computed
和 ref
实现一个双倍计数器,并展示 Vue 3 中的响应式机制。
<template>
<div>
<p>计数值:{{ count }}</p>
<p>双倍计数值:{{ doubleCount }}</p>
<button @click="increment">增加</button>
</div>
</template>
<script>
import { ref, computed } from 'vue';
export default {
setup() {
const count = ref(0);
const doubleCount = computed(() => count.value * 2);
const increment = () => count.value++;
return { count, doubleCount, increment };
}
}
</script>
2.3 watch
实现副作用逻辑
通过 watch
,我们可以实现对响应式数据的精确监听。
<template>
<div>
<p>计数值:{{ count }}</p>
<button @click="increment">增加</button>
</div>
</template>
<script>
import { ref, watch } from 'vue';
export default {
setup() {
const count = ref(0);
const increment = () => count.value++;
watch(count, (newValue, oldValue) => {
console.log(`count 从 ${oldValue} 变为 ${newValue}`);
});
return { count, increment };
}
}
</script>
3. 组合式 API 的优势
- 逻辑拆分和复用:在 Vue 2 中,逻辑往往是通过生命周期钩子、数据和方法进行组织的,导致同一逻辑分散在组件的不同位置。而 Vue 3 的 Composition API 可以将相关的逻辑组合在一起,更容易复用和模块化。
- 代码更简洁:Composition API 允许通过函数方式组织代码,使得代码逻辑更加集中。
- 灵活性高:它为大型项目提供了更好的逻辑复用性,并且可以无缝集成 TypeScript。
4. 总结
Vue 3 的 Composition API 为我们提供了一种更灵活的方式来组织和复用代码。通过 setup
函数,我们可以创建更简洁、更易维护的组件。核心的 ref
、reactive
、computed
和 watch
等工具帮助我们轻松管理响应式状态,同时生命周期钩子也变得更易于理解和使用。
对于开发大型项目,Composition API 提供了更强的灵活性和可维护性,建议在学习 Vue 3 时优先掌握这一新特性。