Vue.js 2.x 的源碼託管在 src 目錄,而後依據功能拆分出了 compiler(模板編譯的相關代碼)、core(與平臺無關的通用運行時代碼)、platforms(平臺專有代碼)、server(服務端渲染的相關代碼)、sfc(.vue 單文件解析相關代碼)、shared(共享工具代碼)等目錄。vue
Vue.js 3.0,整個源碼是經過 monorepo 的方式維護的,根據功能將不一樣的模塊拆分到 packages 目錄下面不一樣的子目錄中,每一個 package 有各自的 API、類型定義和測試。node
Vue.js 2.x 選用 Flow 作類型檢查,來避免一些因類型問題致使的錯誤,可是 Flow 對於一些複雜場景類型的檢查,支持得並很差。算法
Vue.js 3.0 拋棄了 Flow ,使用 TypeScript 重構了整個項目。 TypeScript 提供了更好的類型檢查,能支持複雜的類型推導;因爲源碼就使用 TypeScript 編寫,也省去了單獨維護 d.ts 文件的麻煩。typescript
Vue.js 2.x 內部是經過 Object.defineProperty 這個 API 去劫持數據的 getter 和 setter 來實現響應式的。這個 API 有一些缺陷,它必須預先知道要攔截的 key 是什麼,因此它並不能檢測對象屬性的添加和刪除。api
Vue.js 3.0 使用了 Proxy API 作數據劫持,它劫持的是整個對象,天然對於對象的屬性的增長和刪除都能檢測到。性能優化
在 Vue.js 2.x 中,對於一個深層屬性嵌套的對象,要劫持它內部深層次的變化,就須要遞歸遍歷這個對象,執行 Object.defineProperty 把每一層對象數據都變成響應式的,這無疑會有很大的性能消耗。函數
在 Vue.js 3.0 中,使用 Proxy API 並不能監聽到對象內部深層次的屬性變化,所以它的處理方式是在 getter 中去遞歸響應式,這樣的好處是真正訪問到的內部屬性纔會變成響應式,簡單的能夠說是按需實現響應式,就沒有那麼大的性能消耗。工具
Vue.js 2.x 的數據更新並觸發從新渲染的粒度是組件級的,單個組件內部須要遍歷該組件的整個 vnode 樹。性能
Vue.js 3.0 作到了經過編譯階段對靜態模板的分析,編譯生成了 Block tree。Block tree 是一個將模版基於動態節點指令切割的嵌套區塊,每一個區塊內部的節點結構是固定的。每一個區塊只須要追蹤自身包含的動態節點。測試
Vue.js 2.x 中,若是有一個組件傳入了slot,那麼每次父組件更新的時候,會強制使子組件update,形成性能的浪費。
Vue.js 3.0 優化了slot的生成,使得非動態slot中屬性的更新只會觸發子組件的更新。動態slot指的是在slot上面使用v-if,v-for,動態slot名字等會致使slot產生運行時動態變化可是又沒法被子組件track的操做。
使用 Vue.js 2.x 編寫組件本質就是在編寫一個「包含了描述組件選項的對象」,能夠把它稱爲 Options API。咱們按照 data、props、methods、computed 這些不一樣的選項來書寫對應的代碼。這種方式對於小型的組件可能代碼還能一目瞭然,但對於大型組件要修改一個邏輯點,可能就須要在單個文件中不斷上下切換和尋找邏輯代碼。
Vue.js 3.0 提供了一種新的 API:Composition API,它有一個很好的機制去解決這樣的問題,就是將某個邏輯關注點相關的代碼全都放在一個函數裏,這樣在修改一個邏輯時,只須要改那一塊的代碼了。
在 Vue.js 2.x 中,咱們通常會用 mixins 去複用邏輯。當抽離並引用了大量的mixins,你就會發現兩個不可避免的問題:命名衝突和數據來源不清晰。
Vue.js 3.0 設計的 Composition API,在邏輯複用方面就會頗有優點了。