vue 3.0和2.0区别_一文看懂 Vue.js 3.0 的优化
Vue.js 從 1.x 到 2.0 版本,最大的升級就是引入了虛擬 DOM 的概念,它為后續做服務端渲染以及跨端框架 Weex 提供了基礎。
Vue.js 2.x 發展了很久,現在周邊的生態設施都已經非常完善了,而且對于 Vue.js 用戶而言,它幾乎滿足了我們日常開發的所有需求。在迭代 2.x 版本的過程中,小右發現了很多需要解決的痛點,比如源碼自身的維護性,數據量大后帶來的渲染和更新的性能問題,一些想舍棄但為了兼容一直保留的雞肋 API 等;另外,小右還希望能給開發人員帶來更好的編程體驗,比如更好的 TypeScript 支持、更好的邏輯復用實踐等,所以他希望能從源碼、性能和語法 API 三個大的方面優化框架。
那么接下來,我們就一起來看一下 Vue.js 3.0 具體做了哪些優化, 了解Vue.js 3.0的升級給我們開發帶來什么收益。
一、源碼優化1更好的代碼管理方式:monorepo>>>>Vue.js 2.x
源碼托管在 src 目錄
src
├── compiler ? ? ? ?# 編譯相關
├── core ? ? ? ? ? ?# 核心代碼
├── platforms ? ? ? # 不同平臺的支持
├── server ? ? ? ? ?# 服務端渲染
├── sfc ? ? ? ? ? ? # .vue 文件解析
├── shared ? ? ? ? ?# 共享代碼
Vue.js 3.0
monorepo 把這些模塊拆分到不同的目錄中,每個模塊有各自的API類型定義和測試。這樣使得模塊拆分更細化,職責劃分更明確,模塊之間的依賴關系也更加明確,開發人員也更容易閱讀、理解和更改所有模塊源碼,提高代碼的可維護性。
@vue
├── compiler-core
│ ? ├── LICENSE
│ ? ├── README.md
│ ? ├── dist
│ ? │ ? ├── compiler-core.cjs.js
│ ? │ ? ├── compiler-core.cjs.prod.js
│ ? │ ? ├── compiler-core.d.ts
│ ? │ ? └── compiler-core.esm-bundler.js
│ ? ├── index.js
│ ? └── package.json
├── compiler-dom
│ ? …
├── reactivity
│ ? …
├── runtime-core
│ ? …
├── runtime-dom
│ ? …
└── shared
? ?…
Vue.js 2.x
使用Flow做類型檢查,Flow 是 Facebook 出品的 JavaScript 靜態類型檢查工具,它可以以非常小的成本對已有的 JavaScript 代碼遷入,非常靈活。但是Flow 對于一些復雜場景類型的檢查,支持得并不好。
>>>>Vue.js 3.0
使用 TypeScript 重構了整個項目。TypeScript提供了更好的類型檢查,能支持復雜的類型推導。
二、性能優化1源碼體積優化>>>>Vue.js 3.0
移除一些冷門的 feature(比如 filter、inline-template 等);
引入 tree-shaking 的技術,減少打包體積;
2數據劫持優化>>>>Vue.js 2.x
Vue.js 2.x是采用數據劫持結合發布者-訂閱者模式的方式來達到數據響應效果的。大體思路參考下圖。(詳細原理自行學習,哈哈)
Vue.js 2.x 內部是通過 Object.defineProperty 這個 API 去劫持數據的 getter 和 setter,具體是這樣的:
Object.defineProperty(data,?'a',{??get(){
????//?track
??},
??set(){
????//?trigger
??}
})
但這個 API 有一些缺陷:
它必須預先知道要攔截的 key 是什么,所以它并不能檢測對象屬性的添加和刪除。盡管 Vue.js 為了解決這個問題提供了 $set 和 $delete 實例方法;
對于嵌套層級較深的對象,如果要劫持它內部深層次的對象變化,就需要遞歸遍歷這個對象,執行 Object.defineProperty 把每一層對象數據都變成響應式的。如果我們定義的響應式數據過于復雜,這就會有相當大的性能損耗;
>>>>Vue.js 3.0
為了解決上述 2 個問題,Vue.js 3.0 使用了 Proxy API 做數據劫持,它的內部是這樣的:
observed?=?new?Proxy(data,?{??get()?{
????//?track
??},
??set()?{
????//?trigger
??}
})
使用了 Proxy API 做數據劫持,它劫持的是整個對象,對于對象的屬性的增加和刪除都能檢測到。
Proxy API 并不能監聽到內部深層次的對象變化,因此 Vue.js 3.0 的處理方式是在 getter 中去遞歸響應式,這樣的好處是真正訪問到的內部對象才會變成響應式,而不是無腦遞歸,這樣無疑也在很大程度上提升了性能,我會在后面分析響應式章節詳細介紹它的具體實現原理?。
3編譯優化>>>>Vue.js 2.x
通過數據劫持和依賴收集,Vue.js 2.x 的數據更新并觸發重新渲染的粒度是組件級的,雖然 Vue 能保證觸發更新的組件最小化,但在單個組件內部依然需要遍歷該組件的整個 vnode 樹。這就會導致 vnode 的性能跟模版大小正相關,跟動態節點的數量無關,當一些組件的整個模版內只有少量動態節點時,這些遍歷都是性能的浪費。
>>>>Vue.js 3.0
通過編譯階段對靜態模板的分析,編譯生成了 Block tree。Block tree 是一個將模版基于動態節點指令切割的嵌套區塊,每個區塊內部的節點結構是固定的,而且每個區塊只需要以一個 Array 來追蹤自身包含的動態節點。借助 Block tree,Vue.js 將 vnode 更新性能由與模版整體大小相關提升為與動態內容的數量相關。
三、語法 API 優化1邏輯組織優化>>>>Vue.js 2.x
在 Vue.js 2.x 版本中,編寫組件本質就是在編寫一個“包含了描述組件選項的對象”,我們把它稱為 Options API。Options API 的設計是按照 methods、computed、data、props 這些不同的選項進行分類。和一個邏輯點相關的代碼可能寫在多個Option里,非常分散,如果需要修改一個邏輯點,就需要在單個文件中不斷切換和尋找。
>>>>Vue.js 3.0
Vue.js 3.0 提供了一種新的 API:Composition API,它有一個很好的機制去解決這樣的問題,就是將某個邏輯關注點相關的代碼全都放在一個函數里,這樣當需要修改一個功能時,就不再需要在文件中跳來跳去。
2邏輯復用優化>>>>Vue.js 2.x
我們通常會用 mixins 去復用邏輯。使用單個 mixin 似乎問題不大,但是當我們一個組件混入大量不同的 mixins 的時候,會存在兩個非常明顯的問題:命名沖突和數據來源不清晰。
每個 mixin 都可以定義自己的 props、data,它們之間是無感的,所以很容易定義相同的變量,導致命名沖突;
對組件而言,如果模板中使用不在當前組件中定義的變量,那么就會不太容易知道這些變量在哪里定義的,這就是數據來源不清晰;
>>>>Vue.js 3.0
使用 hook 函數,整個數據來源清晰了,也不會出現命名沖突的問題。
3更好的類型支持因為它們都是一些函數,在調用函數時,自然所有的類型就被推導出來了。不像 Options API 所有的東西使用 this。
4tree-shaking 友好tree-shaking有一個兩個要求(對tree-shaking不熟的,還是自行去學習,哈哈):
必須是import導入。
是必須是單個函數或常量導出
>>>>Vue.js 2.x
直接導出的是整個vue實例,如果我們只是簡單的用某一些功能的話就有點累贅。
>>>>Vue.js 3.0
用到的函數可以通過import聲明,對“按需加載”有更好的支持。
注意Composition API 屬于 API 的增強,它并不是 Vue.js 3.0 組件開發的范式,如果組件足夠簡單,可以使用 Options API。
本文主要總結了 Vue.js 3.0 升級做了幾個方面的優化,以及為什么會需要這些優化。希望學習完后我們也可以像小右一樣去審視自己的工作,有哪些痛點,找到可以改進和努力的方向并實施,只有這樣才能夠不斷提升自己的能力,工作上也會有不錯的產出。
資料參考來源:
黃軼老師--《Vue.js 3.0 核心源碼解析》課程
感謝閱讀~~掃碼關注我們前端麻辣燙仙女都在看點點點,贊和在看都在這兒! 與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的vue 3.0和2.0区别_一文看懂 Vue.js 3.0 的优化的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python分布式框架有哪些_Pytho
- 下一篇: axios请求接口http_Vue实战0