写在前面
最近在看一般关于vue的书,里面提到了“Vue 3的组合式API可以解决功能分散、难以维护的问题”,一时难以理解,特地查了下资料,在这里记录下。
组合式与选项式示例对比
假设我们想要创建一个简单的计数器组件,它有一个按钮,每次点击按钮时,计数器的值会增加1。
选项式 API 示例
<template>
<div>
<p>Count: {{ count }}</p>
<button @click="increment">Increment</button>
</div>
</template>
<script>
export default {
data() {
return {
count: 0,
timer: null,
};
},
methods: {
increment() {
this.count++;
},
},
mounted() {
console.log('Component has been mounted');
// 模拟一个定时器
this.timer = setInterval(() => {
this.count++;
}, 1000);
},
beforeDestroy() {
console.log('Component will be destroyed');
clearInterval(this.timer);
},
};
</script>
在这个例子中:
data
函数返回一个对象,其中包含了组件的状态(count
)。methods
对象中定义了increment
方法,该方法用于增加count
的值。mounted
钩子在组件挂载后执行,输出一条消息并设置一个定时器每秒增加 count 的值。beforeDestroy
钩子在组件卸载前执行,清除定时器。
组合式 API 示例
<template>
<div>
<p>Count: {{ count }}</p>
<button @click="increment">Increment</button>
</div>
</template>
<script setup>
import { ref, onMounted, onUnmounted } from 'vue';
// 定义响应式数据
const count = ref(0);
let timer = null;
// 定义方法
function increment() {
count.value++;
}
// 生命周期钩子
onMounted(() => {
console.log('Component has been mounted');
// 模拟一个定时器
timer = setInterval(() => {
count.value++;
}, 1000);
});
onUnmounted(() => {
console.log('Component will be destroyed');
clearInterval(timer);
});
</script>
在这个例子中:
- 使用
ref
创建了一个响应式的count
变量。ref
返回一个包含.value
属性的对象,这个属性用来读取或修改变量的值。 increment
函数直接修改了count
的值。注意这里需要使用count.value
来访问或设置count
的值。- 使用
<script setup>
语法糖,它可以自动暴露所有顶层变量和函数到模板中,因此不需要显式地返回它们。 - 使用
onMounted
钩子在组件挂载后执行,输出一条消息并设置一个定时器每秒增加count
的值。 - 使用
onUnmounted
钩子在组件卸载前执行,清除定时器。
对比
通过上面代码我们可以做出如下对比:
代码组织
- 选项式 API:逻辑按照 data, methods 等选项来组织,适合小型项目。
- 组合式 API:逻辑可以按功能模块来组织,适合大型项目,易于理解和维护。
响应式数据
- 选项式 API:通过 data 函数返回的对象来管理状态,使用 this 关键字来访问。
- 组合式 API:通过 ref 或 reactive 来管理状态,直接使用变量名访问,不需要 this。
方法定义
- 选项式 API:在 methods 对象中定义方法。
- 组合式 API:直接在
<script setup>
中定义函数,它可以自动暴露所有顶层变量和函数到模板中。
生命周期钩子
- 选项式 API:使用 created, mounted 等生命周期钩子。
- 组合式 API:使用 onMounted, onUnmounted 等函数来替代。
官方对于组合式API的说明
官网地址:cn.vuejs.org/guide/extra…
这里只给出两个风格的对比,从上面我们也可以看出组合式API可以将代码变得更加紧凑,修改起来也相对集中。
除了以上可以肉眼可观察的好处外,还有以下优点:
更好的类型推导 选项式 API 是在 2013 年被设计出来的,那时并没有把类型推导考虑进去,因此不得不做了一些复杂到夸张的类型体操才实现了对选项式 API 的类型推导。 相比之下,组合式 API 主要利用基本的变量和函数,它们本身就是类型友好的。用组合式 API 重写的代码可以享受到完整的类型推导,不需要书写太多类型标注。
更小的生产包体积
搭配 <script setup>
使用组合式 API 比等价情况下的选项式 API 更高效,对代码压缩也更友好。这是由于 <script setup>
形式书写的组件模板被编译为了一个内联函数,和 <script setup>
中的代码位于同一作用域。不像选项式 API 需要依赖 this
上下文对象访问属性,被编译的模板可以直接访问 <script setup>
中定义的变量,无需从实例中代理。
总结
选项式API有一个很大的缺点:一个组件可能定义很多数据、属性和方法等来实现多个功能,比较分散,如果项目小,可以清晰明了。但是一个大项目的一个组件可能在methods中包含很多个方法,往往分不清哪个方法对应哪个功能,如果要进行对应功能的修改,可能需要上下来回搜索,非常影响效率且不好维护。所以Vue 3开始使用组合式API来解决这样的问题,它可以将不同功能逻辑的关注点划分成模块,再组合起来,这样在需要修改对应功能时可以在对应模块中搜索,就方便高效很多了。当一个组件的逻辑变得复杂的时候,就应当考虑用组合式API替换选项式API。
参考
原文地址:mp.weixin.qq.com/s/-ya8kzta3…