僅僅為了方便學習記錄信息辱匿,未有其他用途键痛。(采摘)
Vue2與Vue3的響應式
vue2的響應式
核心:
*對象: 通過defineProperty對對象的已有屬性值的讀取和修改進行劫持(監(jiān)視/攔截)
*數(shù)組: 通過重寫數(shù)組更新數(shù)組一系列更新元素的方法來實現(xiàn)元素修改的劫持
問題:
*對象直接新添加的屬性或刪除已有屬性, 界面不會自動更新
*直接通過下標替換元素或更新length, 界面不會自動更新 arr[1] = {}
// 重新定義數(shù)組原型,Object.defineProperty不具備監(jiān)聽數(shù)組的方法
const oldArrayProperty = Array.prototype;
const arrProto = Object.create(oldArrayProperty);
["push", "pop", "shift", "unshift", "splice"].forEach(
(methodName) =>
(arrProto[methodName] = function () {
updateView();
oldArrayProperty[methodName].call(this, ...arguments);
})
);
function observer(target){
if(typeof target !== 'object' || target === null){
return target
}
// 如果是數(shù)組類型,重寫數(shù)組原型的方法("push","pop","shift","unshift","splice")
if(Array.isArray(target)){
target.__proto__ == arrProto;
}
// 如果是對象匾七,遍歷對象所有的屬性絮短,并使用Object.defineProperty把這些屬性全部轉(zhuǎn)為getter/setter
for(let key in target){
defineReactive(target,key,target[key])
}
}
function defineReactive(target, key, value){
// 如果對象有更多的層級,再次調(diào)用observer監(jiān)聽方法昨忆,實現(xiàn)深層次的監(jiān)聽丁频。
observer(value);
Object.defineProperty(target, key, {
get(){
return value;
},
set(newValue){
// 設置值的時候也需要深度監(jiān)聽
observer(value);
if(newValue !== value){
value = newValue;
// 數(shù)據(jù)驅(qū)動視圖,如果數(shù)據(jù)改變邑贴,就調(diào)用視圖更新的方法席里。對應到Vue中是執(zhí)行VDOM
updateView();
}
}
})
}
Vue3的響應式
核心:
*通過proxy(代理): 攔截對data任意屬性的任意(13種)操作, 包括屬性值的讀寫, 屬性的添加, 屬性的刪除等...
*通過 Reflect(反射): 動態(tài)對被代理對象的相應屬性進行特定的操作.
const user = {
name: "John",
age: 12
};
/*
proxyUser是代理對象, user是被代理對象
后面所有的操作都是通過代理對象來操作被代理對象內(nèi)部屬性
*/
const proxyUser =new Proxy(user, {
// 攔截讀取屬性值
get (target, prop) {
return Reflect.get(target, prop)
},
// 攔截設置屬性值或添加新屬性
set (target, prop, value) {
return Reflect.set(target, prop, value)
},
// 攔截刪除屬性
deleteProperty (target, prop) {
return Reflect.deleteProperty(target, prop)
}
})
proxyUser.name = 'bob'
認識vue3<===========================>Composition API(常用)