1.底层原理:数据的劫持,通过ES6中的defineproperty方法实现:
// var obj = {};
// Object.defineProperty(obj, 'name', {
// get: function() {
// console.log('我被获取了')
// return val;
// },
// set: function (newVal) {
// console.log('我被设置了')
// }
// })
// obj.name = 'fei';//在给obj设置name属性的时候,触发了set这个方法
// var val = obj.name;//在得到obj的name属性,会触发get方法
上边已经实现了简单的数据绑定,如果把它与表单框结合起来并添加一个监听器的情况下:
var obj = {};
var demo = document.querySelector('#demo')
var inp = document.querySelector('#inp')
Object.defineProperty(obj, 'name', {
get: function() {
// console.log('获取')
return val;
},
set: function (newVal) {//当该属性被赋值的时候触发
// inp.value = newVal;
demo.innerHTML = newVal;
}
})
inp.addEventListener('input', function(e) {
// 给obj的name属性赋值,进而触发该属性的set方法
obj.name = e.target.value;
});
// obj.name = '';//在给obj设置name属性的时候,触发了set这个方法
// var val = obj.name
当inp的value值发生改变时demo的innerHTML也会随之发生改变,这样就实现了简单的数据双向绑定
Vue数据的劫持结合发布者-订阅者模式实现数据的双向绑定:
(1)、通过observer(即objectdefindproperty的set)循环递归对所有数据对象进行监听,这样的话给每个对象赋值就会触发setter,那么就能监听到数据的变化,
(2)、实现一个指令解析器compile,对每个dom节点的指令进行扫描解析,根据指令模板替换数据,绑定相应的更新函数,
(3)、实现一个Watcher(即订阅者,即每个指令绑定的属性),作为连接Observer和Compile的桥梁,能够订阅并收到每个属性变动的通知,执行指令绑定的相应回调函数,从而更新视图
小弟不才,对于发布者、订阅者模式认知较浅,欢迎大佬指教...