Vue原生实现数据双向绑定,defineProperty和Pro
2020-04-16 本文已影响0人
随风飞2019
<h4 id="text"></h4>
<input type="text" id="box" oninput="changeInput(this.value)">
<script>
let obj = {name:"张三丰"};
let newName = obj.name;
Object.defineProperty(obj,"name",{
get(){
console.log("get")
return newName
},
set(val){
console.log('set')
newName=val;
document.getElementById("text").innerText=newName;
document.getElementById("box").value=newName;
}
})
console.log(obj.name);
obj.name="张无忌";
console.log(obj.name)
function changeInput(e){
obj.name = e
}
</script>
数据双向绑定是Vue的一个重要特点,使得整个框架可以基于数据驱动实现各种数据渲染及交互。
Vue2利用Object.defineProperty来劫持data数据的getter和setter操作。这使得data在被访问或赋值时,动态更新绑定的数据的页面元素。
Object.defineProperty存在的问题
- 只能劫持一个属性,需要对对象遍历进行批量劫持
- 新增数据无法实现
- 无法监听数组变化
<h4 id="text"></h4>
<input type="text" id="box" oninput="changeInput(this.value)">
<script>
let obj = {name:"张三丰"};
let p = new Proxy(obj,{
get(target,key){
console.log("get")
return target[key]
},
set(target,key,val){
console.log('set');
target[key]=val;
document.getElementById("text").innerText=target[key];
document.getElementById("box").value=target[key];
}
})
console.log(p.name);
p.name="张无忌";
console.log(p.name)
function changeInput(e){
p.name = e
}
</script>
Proxy第一个参数是要劫持的目标对象,第二个参数是一个处理器对象
get()和set()是最常用的两个方法
当执行一个操作时定义代理行为的函数,拦截所有发生在data数据上的操作
Object.defineProperty只能监听属性,而Proxy能监听整个对象
Object.defineProperty只能监听对象一个属性,通过遍历监听所有
Proxy可以监听整个对象,不用再去遍历所有属性进行劫持了,这样就省去了遍历元素
Object.defineProperty不能监测到数组变化,Proxy可以。