【vue】vue2和vue3分别实现数据侦听


Object.defineProperty(obj, prop, descriptor)

在js原生对象中,实现数据侦听的方法就是defineProperty。

使用示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var obj = new Object();
var value;
Object.defineProperty(obj,'name',{
get: function () {
console.log(`get${obj['name']} `);
return value;//必须return一个值,作为name属性的值
},
set: function (newvalue) {
console.log('set it');
value = newvalue;//同步把value的值进行更新
}
});
console.log(obj);
console.log(obj.name);//get it
obj.name = ’aaaaa‘;//set it
console.log(obj.name);//get it

vue2中使用defineProperty中实现数据侦听

建立一个html文件,dom结构如下

1
<div class="wrapper"></div>

编写侦听函数

1
2
3
4
5
6
7
8
function observe(target) {
if (typeof target !== "null" && typeof target !== "object") {
return target;
}
for (let key in target) {
defineReactive(target, key, target[key]);
}
}

实现侦听的函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function defineReactive(target, key, value) {
observe(value); // 使用递归,实现深度监听
Object.defineProperty(target, key, {
get() {
return value;
},
set(newValue) {
if (value !== newValue) {
value = newValue;
updateView(JSON.stringify(target));
} else {
console.log("value == newValue");
}
}
});
}

当数据更改时,更新视图

1
2
3
4
5
6
7
8
9
10
11
function updateView(value) {
document.querySelector(".wrapper").innerText = value;
}

let serveObj = {
name: "aaaccc",
age: 11,
other: {
sex: "f"
}
};
1
2
3
observe(serveObj); 

serveObj.name = "sdfdsfsdfsd" // dom会实时改变innerHtml的内容 。

proxy

拦截代理,拦截对应的操作后,进行处理,会新生成一个对象,然后通过proxy生产的对象去改变原对象。

使用方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
let obj = { a: 1 };
let proxy = new Proxy(obj, {
get(target, key) {
return target[key];
},
set(target, key, value, proxy) {
target[key] = value;
document.querySelector(".wrapper").innerText = JSON.stringify(proxy);
}
});

proxy.b = 1;
obj // {a: 1, b: 1}