vue2.0的双向数据绑定其实就是用了es5新增加的Object.defineProperty来进行数据劫持的
<span id="spanName"></span>
<input type="text" id="inputName">
let obj = { name : '' };
let newObj = Object.parse(Object.stringify(obj)); // 深拷贝
Object.defineProperty(obj,'name',{ //数据拦截obj里面的name属性
get(){
return newObj.name; //这里不能return obj.name 因为这样算获取会重新执行get方法造成死循环,只能用新变量
}
set(val){
if(val === newObj.name) return;
newObj.name = val;
observer();
}
})
// 监听方法
function observer() {
spanName.innerHtml = obj.name;
inputName.value = obj.name;
}
inputName.oninput = function(){
obj.name = this.value;
}
存在的问题:
1.数据劫持时需要对原始数据进行克隆
2.需要分别给对象中的每一个属性设置监听(所以必须遍历对象的每个属性)
3.不能监听数组的变化
vue3.0运用的是es6的proxy来进行数据劫持的
let obj = {};
obj = new Proxy(obj,{ //拦截这个对象obj
get(target,prop){ //target就是拦截的对象obj,prop是对象属性
return target[prop];
}
set(target,prop,value){ // 设置的value值
target[prop] = value;
observer();
}
})
// 监听方法
function observer() {
spanName.innerHtml = obj.name;
inputName.value = obj.name;
}
inputName.oninput = function(){
obj.name = this.value; //赋值
}
proxy可以直接监听对象而非属性,可以直接监听数组的变化