在vue中双向数据绑定原理,我们一般都是用v-model来实现的 ,但一般在面试话会问到其实现的原理,
方法比较简单,就是利用了es5中的一个方法.Object.defineproperty(),它有三个参数,
Object.defineproperty(obj,'val',attrObject), 参数1: obj是属性所在的对象,参数2: 'val',属性名,它是一个string类型,参数3: {}属性所描述的对象
详情可以看Object.defineproperty的文档
下面直接上demo,
html代码:
js代码
var inp1 = document.getElementById('inp1')
var inp2 = document.getElementById('inp2')
var obj ={}
Object.defineProperty(obj,'val',{ // 传入obj对象的一个属性 属性名是自定义的
set: function(newval){ // 通过set方法可以拿到新的值
// console.log(newval)
inp1.value= newval
inp2.innerHTML= newval
}
})
// 给输入框一个监听事件 监听变化时重新赋值
inp1.addEventListener('keyup',function(e){
// console.log(e.target.value)
obj.val = e.target.value
})
效果图如下:
.........
var childOb = !shallow && observe(val);
Object.defineProperty(obj, key, {
enumerable: true,
configurable: true,
get: function reactiveGetter() {
var value = getter ? getter.call(obj) : val;
if (Dep.target) {
dep.depend();
if (childOb) {
childOb.dep.depend();
if (Array.isArray(value)) {
dependArray(value);
}
}
}
return value
},
set: function reactiveSetter(newVal) {
var value = getter ? getter.call(obj) : val;
/* eslint-disable no-self-compare */
if (newVal === value || (newVal !== newVal && value !== value)) {
return
}
/* eslint-enable no-self-compare */
if (customSetter) {
customSetter();
}
// #7981: for accessor properties without setter
if (getter && !setter) {
return
}
if (setter) {
setter.call(obj, newVal);
} else {
val = newVal;
}
childOb = !shallow && observe(newVal);
dep.notify();
}
});
.........