vue双向绑定的原理是经过Object.defineProperty()劫持数据结合发布者-订阅者模式的方式来实现的。html
Object.defineProperty()vue
Object.defineProperty()方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象。this
语法:Object.defineProperty(obj,prop,descriptor); obj: 要在其上定义属性的对象。 prop: 要定义或修改的属性的名称。 descriptor: 将被定义或修改的属性描述符。
这里用到了Object.defineProperty()的get和set方法。spa
get:当访问该属性时,该方法会被执行,方法执行时没有参数传入,可是会传入this
对象(因为继承关系,这里的this
并不必定是定义该属性的对象)。双向绑定
set:当属性值修改时,触发执行该方法。该方法将接受惟一参数,即该属性新的参数值。code
具体用法请浏览此处htm
简单实现对象
<input type="text" id="model" /> <div id="modelText"></div>
let modelInfo = {}; let defaultValue = 'Hello Object.defineProperty'; let model = document.getElementById('model'); let text = document.getElementById('modelText'); model.value = defaultValue; text.innerText = defaultValue; /** * writable属性的值是否能够被重写。设置为true能够被重写;设置为false,不能被重写。默认为false。 * value属性对应的值,能够使任意类型的值,默认为undefined * configuable是否能够删除目标属性或是否能够再次修改属性的特性(writable, configurable, enumerable)。设置为true能够被删除或能够从新设置特性;设置为false,不能被能够被删除或不能够从新设置特性。默认为false。 * enumerable此属性是否能够被枚举(使用for...in或Object.keys())。设置为true能够被枚举;设置为false,不能被枚举。默认为false。 */ Object.defineProperty(modelInfo,'key',{ get(){ return defaultValue; }, set(value){ defaultValue = value; model.value = value; text.innerText = value; } }); model.addEventListener('input',function(){ modelInfo.key = this.value; });
若是想要深刻了解,建议看vue的双向绑定原理及实现。blog