Vue2.X 双向数据绑定使用的是 Object.defineProperty(),Vue3 使用的是 Proxy。
Object.defineProperty()
Object.defineProperty(obj, prop, descriptor)
obj
要定义属性的对象。
prop
要定义或修改的属性的名称或 Symbol 。
descriptor
要定义或修改的属性描述符。
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<input class="inp-text" type="text">
<div class="text-box"></div>
</body>
<script>
let obj = {};
Object.defineProperty(obj, 'name', {
set: function(newValue){
console.log('触发setter');
document.querySelector('.text-box').innerHTML = newValue;
document.querySelector('.inp-text').value = newValue;
},
get: function(){
console.log('触发getter');
}
});
document.querySelector('.inp-text').addEventListener('input', function(e){
obj.name = e.target.value;
}, false);
</script>
</html>
Proxy
const p = new Proxy(target, handler)
target
要使用Proxy
包装的目标对象(可以是任何类型的对象,包括原生数组,函数,甚至另一个代理)。
handler
一个通常以函数作为属性的对象,各属性中的函数分别定义了在执行各种操作时代理p
的行为。
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="div1">
<input type="text" v-model="name"><br>
姓名:{{name}}<br>
年龄:{{age}}
</div>
</body>
<script>
let el=document.getElementById('div1');
let template=el.innerHTML;
let _data={
name: 'liangzai',
age: 18
};
let data=new Proxy(_data, {
set(obj, name, value){
//alert(`有人视图设置 ${name}=>${value}`);
obj[name]=value;
//数据变了
//console.log('数据变了');
render();
}
});
render();
function render(){
//渲染
el.innerHTML=template.replace(/\{\{\w+\}\}/g, str=>{
str=str.substring(2, str.length-2);
return _data[str];
});
//找所有的v-model
Array.from(el.getElementsByTagName('input'))
.filter(ele=>ele.getAttribute('v-model'))
.forEach(input=>{
let name=input.getAttribute('v-model');
input.value=_data[name];
input.oninput=function (){
console.log(1)
data[name]=this.value;
};
});
}
</script>
</html>
网友评论