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,也是十分友好的。