实现思路:
1. 实现一个数据监听器Observer,能够对数据对象的所有属性进行监听,如有变动可拿到最新值并通知订阅者
2.实现一个指令解析器Compile,对每个元素节点的指令进行扫描和解析,根据指令模板替换数据,以及绑定相应的更新函数
3. 实现一个Watcher,作为连接Observer和Compile的桥梁,能够订阅并收到每个属性变动的通知,执行指令绑定的相应回调函数,从而更新视图
实现过程代码:
创建一个数据监听器observer
functionobserver(data) {if(({}).toString.call(data) != '[object Object]') returnfor(var key in data) {}}functionobserveProperty(data) {Object,definedProperty(data, key, {},set() {}})}
添加一个订阅器,修改observeProperty方法
// 通过Object.definedProperty来实现数据劫持functionobserveProperty(data, key, val) {var dep = new Dep() observer(data) Object.definedProperty(data, key, {enumerable: true, configurable: false, get() { return val }, set(newVal) { // 添加一个订阅器if(newVal !== val) { val = newVal dep.notify() } } })}
如果写一个订阅器
function Dep() {// 订阅堆也就是咱们下文的Watchersthis.subList = [];}// 订阅Dep.prototype.sub = function(sub) { this.subList.push(sub)}//发布Dep.prototype.notify = function() { this.subList.forEach(item=>{// 通知所有订阅者,更新数据 item.update() })}
什么时候去订阅呢?就是在observeProperty执行get方法的时候去搞定的
functionobserveProperty(data, key, val) {var dep = new Dep()observer(data)Object.definedProperty(data, key, {enumerable: true,configurable: false, get() { Dep.target && dep.sub(Dep.target);return val},set(newVal) {// 添加一个订阅器 if(newVal !== val) { val = newVal dep.notify() } } })}
实现一个watcher
function watcher(vm, exp, cb) {this.vm = vmthis.exp = expthis.cb = cbthis.value = this.get() // 缓存当前值(旧值)}watcher.prototype.update = function() {this.run()}watcher.prototype.get = function() { Dep.target = this// 将当前订阅者指向自己 const value = this.vm[this.exp] // 触发getter,添加自己到属性订阅器中Dep.target = null// 添加完毕,重置return value}watcher.prototype.run = function() {const value = this.get() // 获取新值 const oldValue = this.valueif (value !== oldValue) {this.value = valuethis.cb.call(this.vm, value, oldValue) // 执行Compile中绑定的回调,更新视图 }}郑州看不孕不育哪家医院好:http://www.zzchyy110.com/郑州有哪些好的不孕不育医院:http://www.zzchyy110.com/郑州同济医院:http://www.zzchyy110.com/
6.实现一个compile
// ……
7.最后去关联Observer、Compile和Watcher三者
functionMvvm(data) {observer(data) compile()}
来源:oschina
链接:https://my.oschina.net/u/4531268/blog/4338993