在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(); } }); .........