之前寫的關於 vue3 的文章,好多人吐槽:這些API每次使用都要引入一遍,感覺有點麻煩。
今天我們就來看看 vue3 相比 vue2 的優點有些啥?
為啥有些人說:自從寫了 ts vue3 再也回不到 vue2 啦!
vue3 到底哪裡好?有的人回不到 vue2,而有的人去不了vue3!喜歡的點贊收藏,覆盤不迷路!
一、Vue3 新增的幾個亮點:
- Performance:效能優化
- Tree-shaking :支援搖樹優化
- Composition API :組合式api
- 新增元件:Fragment、Teleport、Supense
- 更好地支援 ts
- Custom Render API:自定義渲染器
二、效能方面的提升
在效能方面,vue3 相比 vue2 ,效能提升了 1.3 ~ 2 倍左右。我們就來看看它是在哪些方面,如何提升的?
2.1、響應式效能提升
1> diff方法優化
diff 演算法是虛擬 DOM 技術的必然產物,它會對新舊 DOM 進行比較,然後將變化的 DOM 更新在真實的 DOM 上。
在 vue2 中,資料發生變化的時候,會生成一個新的 DOM 樹,然後和之前的 DOM 樹進行比較,找到不同的節點然後更新到真實的 DOM 上,比較的過程中,會對沒有發生改變的 DOM 也都會進行比較,就會消耗一定的時間。
在 vue3 中,在建立虛擬 DOM 的時候,會根據 DOM 中的內容新增一個靜態標記,在資料發生改變的時候,就會帶著靜態標記的節點去對比,能夠快速找到變化的 DOM 。
2> 事件偵聽器快取
預設情況下onClick會被視為動態繫結,所以每次都會追蹤它的變化
但是因為是同一個函式,所以不用追蹤變化,直接快取起來複用即可
3> ssr渲染
當存在大量靜態內容時,這些內容會被當做純字串推進一個 buffer 內,即使存在動態繫結,也會通過模板插值潛入進去,這樣會比虛擬 DOM 渲染快得多。
2.2、程式碼體積方面
打包大小減少41%。
vue3 移除了一些不常用的 API,如:inline-template、filter 等,使用 tree-shaking。
Tree Shaking 搖樹優化,指的就是當我們引入一個模組的時候,不引入這個模組的所有程式碼,只引入我們需要的程式碼。
在 vue2 中,很多函式都掛載到全域性 Vue 物件上,如:nextTick、set 函式等,雖然我們不常用,但打包時只要引入 Vue 這些全域性函式會打包進 bundle 中。而 vue3 中,引入tree-shaking,所有的 API 都通過 ES6 模組化的方式引入,這樣就能夠讓 webpack 或 rollup 等打包工具在打包時,就會自動對沒有用到的 API 進行剔除,最小化 bundle 體積。
初次渲染快55%, 更新渲染快133%。元件選擇了按需引入,使得打包後的體積也更小了,所以專案執行的時候速度更快,更順暢了!
2.3、編譯被優化
1> 靜態提升
在 vue2 中,無論元素是否參與更新,每次都會重新建立然後再渲染。
vue3 使用靜態提升後,對於不參與更新的元素,只會被建立一次,在渲染時直接複用就好了。
2> Fragment
模板內不用再建立一個唯一根節點,可以直接放同級標籤和內容。就相當於少了一個節點巢狀渲染。
三、選項式 api VS 組合式 api
3.1、vue3 的組合式 api 相對來說,更有利於維護和封裝。
3.2、組合式 api 高內聚,低耦合。
在 vue2 中採用選項式 api ,會在 vue 檔案的 data、methods、watch、computed 中定義屬性和方法,共同處理頁面邏輯,多個功能相互交叉,纏繞在一起,程式碼過於分散。
而 vue3 新增了組合式 api ,一個功能模組程式碼會集中到一起,實現高內聚,低耦合。提高程式碼的可讀性和可維護性,基於函式組合的 api 更好地重用邏輯程式碼。
組合式api 與 選項式api 對比如下圖:
每個顏色,都代表著一個功能。
3.3、不宜出現 DOM 元素不存在問題。
vue3 中用 setup 函式代替了 vue2 中的 beforeCreate 和 created 。有些同學有時候會在 created 中操作 DOM 元素,有時候報錯了,就在那納悶看不出來問題,為了沒有反應。使用 setup 之後,就不容易出現該問題了。
注意:
vue3 的組合式 api 中的 onUnmounted 代替了 vue2 中的 beforeDestory。
vue3 的組合式 api unmounted 代替了 vue2 中的 destoryed 。
四、proxy 相對 Object.defineProperty 優點有哪些?
proxy 和 Object.defineProperty 都是來實現響應式資料的。
vue3 使用 proxy 來代替 vue2 的 Object.defineProperty 效率更高,值得學習。
1> vue2 利用 Object.defineProperty 來劫持 data 資料的 getter 和 setter 操作,使得 data 在被訪問或賦值時,動態更新繫結的 template 模板。而 Object.defineProperty 必須遍歷所有的預值才能劫持每一個屬性,這一缺點正好能夠被 proxy 解決。
proxy 相比 Object.defineProperty 優點分別為:
- 程式碼的執行效果更快。
- proxy 可以直接監聽物件而不是它的屬性。
- proxy 可以直接監聽陣列的每個元素的變化。
- proxy 不需要初始化的時候遍歷所有屬性,如果有多層巢狀的話,只訪問某個屬性的時候,proxy 能夠快速訪問到,而 Object.defineProperty 還需要遍歷所有屬性,然後逐級向下訪問。
- proxy 返回的是一個新物件,可以直接操作新物件而達到目標。而 Object.defineProperty 操作的是原物件,只能遍歷物件屬性然後對其直接修改。
- proxy 有 13 種攔截方法,不限於 apply、ownKeys、deleteProperty 等,而 Object.defineporperty 不具備。
2> defineProperty 無法監聽物件新增屬性以及無法跟蹤陣列索引以及陣列 length 的問題,proxy 正好解決了該問題。
在 vue2 中,我們給物件新增一個屬性時,如果新增屬性的值發生改變的時候,我們發現檢視並沒有更新,因為新增屬性是無法監聽到的。同樣的,通過下標直接改變陣列,檢視也是無法更新的,也是因為監聽不到。
在 vue3 中新增 proxy ,解決了這些問題。
五、更好的 ts 支援
vue2 不適合使用 ts,在於它的 Options API 風格。
options 是一個簡單的物件,而 ts 是一種型別系統、物件導向的語法,兩個不匹配。
vue3 新增了 defineComponent 函式,使元件在 ts 下,更好的利用引數型別推斷。如:reactive 和 ref 很具有代表性。
六、更先進的元件
1> Fragment
在 vue2 中,每個模板必須有一個根節點,否則就會報錯。
vue3 中可以不需要根節點,多個元素或標籤可並列存在。
2> Teleport
傳送門。可以把 teleport 中的內容新增到任意的節點內,對於巢狀較深的元件來說絕對是一個福音。
3> Supense
允許程式在等待非同步元件渲染一些後備的內容,可以讓我們建立一個平滑的使用者體驗。
總結:
vue 目前是國內最火的前端框架之一,vue3 效能提升、執行速度也比 vue2 好很多。
總之 vue3 就是:
- 讓專案更快
- 讓程式碼更少
- 更易於維護
- 讓我們開發更快,加班更少