1.原理
vue中可以通过v-model指令实现双向数据绑定,那么在vue底层中是如何实现的呢?
其实是使用了es5中的Object.defineProperty()实现的
2.Object.defineProperty()
此方法的作用: 它可以直接在一个对象上定义一个新的属性,或者修改一个对象的现有属性,并且返回这个对象
语法:Object.defineProperty(obj,prop,descriptor)
obj:要在其中定义属性的对象
prop:要定义或修改的属性的名称
descriptor:将被定义或者修改的描述符
然后参数中重点就是最后的描述符
var obj = {}
Object.defineProperty(obj,'val',{
value:123
})
注意:默认情况下这样给对象赋值是无法被更改的
3.如何更改?
在定义时可以在赋值时添加一个属性writable为true时,value才能被赋值运算符改变
ar obj = {};
Object.defineProperty(obj, 'val', {
value: 123,
writable:true,
});
Object.defineProperty(obj, 'val1', {
value: 12366,
writable:true,
});
obj.val=6666 //修改val的值
get: 一个属性提供getter的方法,当访问一个对象的时候该方法会被执行
set: 一个属性提供的setter方法,当属性值被改变时就会执行这个方法,该方法接收一个参数,即是该属性的新值
var o = {}; // 创建一个新对象
// 在对象中添加一个属性与存取描述符的示例
var bValue;
Object.defineProperty(o, "b", {
get: function () {
console.log("获取了值:", bValue)
return bValue;
},
set: function (newValue) {
console.log("设置了新值:", newValue)
bValue = newValue;
},
});
模拟v-model指令实现双向绑定
核心代码:
<input v-model="value" />
<p zl-model="value"></p>
<script>
//代码演示:defineProperty的双向绑定
var obj = {};
Object.defineProperty(obj, 'val', {
set: function (newVal) {
var list = document.querySelectorAll("[v-model=value]");
for (let i = 0; i < list.length; i++) {
if (list[i].nodeName == "INPUT") list[i].value = newVal == undefined ? '' : newVal;
else list[i].innerHTML = newVal == undefined ? '' : newVal;
}
},
get: function () {
return document.querySelector("[v-model=value]").value;
}
});
document.querySelector("[v-model=value]").addEventListener("input", function (e) {
obj.val = e.target.value;
})
</script>
总结:VUE实现双向数据绑定的原理,利用了object.defineProperty()重新定义了获取对象属性值(get)和设置属性值(set)的操作来实现