https://blog.csdn.net/weixin_44475093/article/details/112386778
https://blog.csdn.net/userDengDeng/article/details/114941956
一、vue3的新特性:
1、速度更快
vue3相比vue2
- 重寫了虛擬Dom實現
- 編譯模板的優化
- 更高效的組件初始化
- undate性能提高1.3~2倍
- SSR速度提高了2~3倍
- 體積減小
2、體積更小
通過webpack的tree-shaking功能,可以將無用模塊“剪輯”,僅打包需要的能夠tree-shaking,有兩大好處:
- 對開發人員,能夠對vue實現更多其他的功能,而不必擔憂整體體積過大。
- 對使用者,打包出來的包體積變小了
3、更易維護
compositon Api
composition Api,也就是組合式api,通過這種形式,我們能夠更加容易維護我們的代碼,將相同功能的變量進行一個集中式的管理。
- 可與現有的Options API一起使用
- 靈活的邏輯組合與復用
-
Vue3模塊可以和其他框架搭配使用
image.png
4、 更好的Typescript支持
VUE3是基于typescipt編寫的,可以享受到自動的類型定義提示
5、更接近原生
6、更易使用
第二篇文章
源碼組織方式的變化
使用 typescript 重寫
Composition Api
1、vue.js 3.x 新增的一組 API
2、一組基于函數的API
3、可以更靈活的組織組件的邏輯
性能提升
響應式系統升級
- vue.js 2.x 中響應式系統的核心 defineProperty
- Vue.js 3.x 中使用 proxy 對象重寫響應式系統
1. 可以監聽動態新增的屬性
2. 可以監聽刪除的屬性
3. 可以監聽數組的索引和length屬性
編譯優化
vue.js 2.x 中通過標記靜態根結點,優化 diff 的過程
vue.js 3.x 中標記和提升所有的靜態根節點,diff 的時候只需要對比動態節點的內容。
1、 靜態提升
2、 Patch flag
3、事件監聽緩存:cacheHandlers
優化打包體積
Tree-shaking
二、vue2.x和vue3.x中的雙向數據綁定原理有什么不同?
1、vue2.x實現原理
主要還是通過Object.defineProperty實現雙向數據綁定的。
observe方法的具體邏輯:
Vue.prototype.observe = function(obj) {
var value = '',
_this = this;
for (var key in obj) {
value = obj[key];
(function(key, value) {
if (typeof obj[key] === 'object') {
this.observe(obj[key]);
} else {
Object.defineProperty(_this.$data, key, {
get: function() {
console.log('get value');
return value;
},
set: function(newVal) {
value = newVal;
_this.render();
}
});
}
})(key, value);
}
}
2、vue3.x實現原理
vue3.x主要使用的是proxy對象,proxy對象的定義是:Proxy 對象用于定義基本操作的自定義行為(如屬性查找,賦值,枚舉,函數調用等)。
使用語法如下:
let p = new Proxy(target, handler);
參數如下:
target: 用Proxy包裝的目標對象(可以是任何類型的對象,包括原生數組,函數,甚至另一個代理)。
handler: 一個對象,其屬性是當執行一個操作時定義代理的行為的函數。
var ob = {
a: 1,
b: 2
}
var obj = new Proxy(ob, {
// target就是第一個參數ob, receive就是返回的obj(返回的proxy對象)
get: function(target, key, receive) {
// 返回該屬性值
return target[key];
},
set: function(target, key, newVal, receive) {
// 執行賦值操作
target[key] = newVal;
}
})
3. Proxy的優勢
相比于vue2.x,使用proxy的優勢如下:
- defineProperty只能監聽某個屬性,不能對全對象監聽
- 可以省去for in、閉包等內容來提升效率(直接綁定整個對象即可)
- 可以監聽數組,不用再去單獨的對數組做特異性操作。
4、Proxy帶來的問題:
Proxy的問題在于瀏覽器兼容有點問題,IE下完全不兼容,如果要兼容的話應該是需要添加polyfill等內容。
三、Vue3 如何重寫 Vdom
https://blog.csdn.net/qq_26443535/article/details/114079572
1、patch flag 優化靜態樹
當我們創建了一個動態的 dom 元素,我們發現創建動態 dom 元素的 時候,Vdom 除了模擬出來了它的基本信息之外,還給它加了一個標 記: 1 /* TEXT */,這個標記就叫做 patch flag(補丁標記)
patch flag 的強大之處在于,當你的 diff 算法走到 _createBlock 函數的時候,會忽略所有的靜態節點,只對有標記的動態節點進行對比。
2、 patch flag 優化靜態屬性
只關注它有變化的部分。
3、靜態提升
剛剛我們提到 Vue3 突破 Vdom 的性能瓶頸的方式是,而在更新時具體的做法就是 靜態樹的提升 和 靜態屬性的提升。
我們已經知道處理后的 Vdom 都在 _createBlock 函數之中,而觀察結果我們發現,所有的靜態元素都被放在了 _createBlock 函數之外了,也就是說他們只會在頁面初始的時候被渲染一次,而在更新的時候,靜>態元素是不予搭理的。這個優化就是 Vue3 的 靜態提升。
4、事件監聽緩存:cacheHandlers
使用cacheHandlers之后,會自動會生成一個內聯函數,在內聯函數里面在引用當前組件最新的onClick,再把這個內聯函數cache起來。
第一次渲染的時候,創建這個內聯函數,并將這個內聯函數緩存起來,后續的更新就從緩存里面讀同一個函數,同一個函數就沒有更新的必要了,通過這種事件監聽緩存的方式也能對性能提升起到作用。
四、vue3的新增的composition Api及使用
https://juejin.cn/post/6875253488017342478
1)Vue3為什么要使用Composition API?
為了解決什么問題?
當前使用Vue2開發的項目,普遍存在的問題:
- 代碼的可讀性隨著組件變大而變差
- 每一種代碼復用的方式,都存在缺點
- TypeScript支持有限
2)常用的api方法:
1、ref和reactive
將數據創建和監聽響應式就需要通過vue暴露出來的功能 ref或reactive。兩者有所區別,ref用于基礎賦值類型的數據,而reactive用于引用類型的數據。
其中基礎賦值類型的值,在setup方法中,需要用 .value的方式進行獲取和修改。因為賦值類型的值如果return出去返回值,就失去了數據的雙綁定。但是在template中,可以進行直接訪問。
我們來討論一下兩者選擇問題:
- 如果是單值,建議ref,哪怕是個單值的對象也可以
const counterRef = ref(1)
const usersRef = ref(['tom', 'jerry'])
- 一個業務關注點有多個值,建議reactive
const mouse = reactive({
x: 0,
y: 0
})
2、watchEffect和watch有啥不同?
這倆方法很相似,都是觀察響應式數據,變化執行副作用函數,但有如下不同:
- watch需要明確指定監視目標,
watch(() => state.counter, (val, prevVal) => {})
- watchEffect不需要
watchEffect(() => {
console.log(state.counter)
})
watch可以獲取變化前后的值
watch是懶執行的,它等效于vue2中的this.$watch(),watchEffect為了收集依賴,要立即執行一次。
3、setup
setup是vue新增的一個選項,它是組件內使用Composition API的入口。setup是在創建vue組件實例并完成props的初始化之后執行
4、生命周期
- beforeCreate -> 使用 setup()
- created -> 使用 setup()
- beforeMount -> onBeforeMount
- mounted -> onMounted
- beforeUpdate -> onBeforeUpdate
- updated -> onUpdated
- beforeDestroy -> onBeforeUnmount
- destroyed -> onUnmounted
- errorCaptured -> onErrorCaptured