浅析vue2中 Options API 和vue3中 Composition API 的对比
Componsition API
是 vue3 的一个很大的更新,也是很大的一个优点。为什么要更新呢?肯定是 vue2 的 Options API
有问题,本文就两者的区别做个介绍。
一、vue2 的 Options API
1、Options API - 又叫选项API
在 VUE2 中我们是如何组织代码的?我们会在一个vue文件中methods,computed,watch,data中等等定义属性和方法,共同处理页面逻辑,我们称这种方式为 Options API。
其优缺点:
- 条例清晰:相同的放在相同的地方,但随着组件功能的增大,关联性会大大降低,组件的阅读和理解难度会增加;
- 调用使用 this,但逻辑过多时 this 会出现问题,比如指向不明等;
- 其本身并不是有效的 js 代码,我们在使用 options API 的时候,需要确切了解我们具体可以访问到哪些属性以及我们访问到的当前属性的行为。在后台 VUE 需要将此属性转换为工作代码,因此我们无法从自动建议和类型检查中受益,因此给我们在使用相关属性时造成了一定弊端。
2、Options 的缺陷 - 反复横跳
一个功能往往需要在不同的vue配置项中定义属性和方法,比较分散,需求简单还好,清晰明了;但是需求复杂之后,就会多出watch,computed,inject,provide等配置,这个.vue文件也会逐渐增大,且一个 methods 中可能包含 10-20 个方法,
你往往分不清哪个方法对应着哪个功能。
相信大部分同学都维护过超过200行的.vue组件,新增或者修改一个需求,就需要分别在data,methods,computed里修改 ,滚动条反复上下移动,我称之为『反复横跳』 比如我们简单的加个拍脑门的需求 加个累加器 ,这种写代码上下反复横条的感觉, 相信大家都懂的。
3、Option的缺陷:mixin 和 this
反复横跳的本质,在于功能的分块组织,以及代码量太大了,如果我们能把代码控制在一屏,自然就解决了,vue2里的解决方案,是使用mixin来混合,比如我们抽离一个counter.js。
这样确实拆分了代码,但是有一个贼严重的问题,就是不打开counter.js,App.vue里的this上,count,add这些属性,是完全不知道从哪来的,你不知道是mixin,还是全局install,还是Vue.prototype.count
设置的,数据来源完全模糊,调试爽死你,这也是option的一个大问题,this是个黑盒,template里写的count和double,完全不知道从哪来的。
同时还会有 mixin 命名冲突的问题。
二、vue3 中的 Composition API
vue3 中的 Composition API 就是用来解决这个问题的:通过组合的方式,把零散在各个data,methods的代码,重新组合,一个功能的代码都放在一起维护,并且这些代码可以单独拆分成函数 。
1、Composition API - 又叫组合式API
在 vue3 Composition API 中,我们的组件代码根据逻辑功能来组织的,一个功能所定义的所有 API 会放在一起(更加的高内聚,低耦合)。这样做即使项目很大,功能很多,我们都能快速的定位到这个功能所用到的所有API,而不像 vue2 Options API 中一个功能所用到的API都是分散的,需要改动功能,到处找API的过程是很费劲的。
其优缺点:
- 其代码更易读,更易理解和学习,没有任何幕后操作
- Composition API的好处不仅仅是以不同的方式进行编码,更重要的是对于代码的重用
- 不受模板和组件范围的限制,也可以准确的知道我们可以使用哪些属性
- 由于幕后没有什么操作,所以编辑器可以帮助我们进行类型检查和建议
2、如何组织及使用:
利用函数我们可以把功能完整独立的拆分成模块或者函数,方便组织代码,并且解决了mixin混乱的问题。
(1)比如我们的累加器 ,抽离一个counter.js
import {ref, computed} from 'vue'
export default function useCounter(){
let count = ref(1)
function add(){
count.value++
}
let double = computed(()=>count.value*2)
return {count, double, add}
}
(2)直接使用
import {reactive, ref, toRefs} from 'vue'
// + import useCounter from './counter'
export default {
setup(){
let val = ref('')
...
// + let {count,double,add} = useCounter()
return {
val, todos, addTodo,
// + count,double,add
}
}
}
再来一个鼠标位置也不在话下,而且可以很好地利用解构赋值的别名,解决mixin的命名冲突问题 mouse.js
let {count,double,add} = useCounter()
let {x, double:doubleX} = useMouse()
return {
val, todos, addTodo,
count,double,add,
x,doubleX
}
具体详情可以学习这篇文章,讲解的很详细:《做了一夜动画,就为让大家更好的理解Vue3的Composition Api - https://mp.weixin.qq.com/s/UZGnk8vhyXuSUFhH6nXHTA》
总结:
- 在逻辑组织和逻辑复用方面,Composition API是优于Options API。因为Composition API几乎是函数,会有更好的类型推断。
- Composition API对 tree-shaking 友好,代码也更容易压缩;
- Composition API中没有对this的使用,减少了this指向不明的情况;
- 如果是小型组件,可以继续使用Options API,也是十分友好的。