vue 双向绑定简单实现 发表于 2017-01-16 深入响应式原理 vue 双向绑定简单实现待更新,需要考虑proxy,代理通知,同步问题,虚拟dom问题 先考虑简单的情况1234567891011class Vue { constructor(options) { this.$options = options this._data = options.data observe(options.data, this._update) this._update() } _update(options) { this.$options.render() }} Observe123456789101112131415161718192021222324252627282930313233343536373839404142class Observe { constructor(value, sub) { if (Array.isArray(value)) { this.observeArry(value, sub) } else { this.walk(obj, sub) } } //defineproperty,每个对象 walk(obj, sub) { const keys = Object.keys(obj) for (let i = 0, len = keys; i < len; i++) { defineReactive(obj, keys[i], obj[keys[i]], sub) } } observeArry(items) { //... }}function observe(value, sub) { new Observe(value, sub)}class Dep { constructor() { this.subs = [] } addSub(sub) { this.subs.push(sub) } removeSub(sub) { this.subs = this.subs.filter(item => item !== sub)//vue中采用splice不知道是否有特殊的意义 } notify() { const subs = this.subs.slice() for (let i = 0, l = subs.length; i < l; i++) { subs[i].update() } }}Dep.target = null defineReactive1234567891011121314151617function defineReactive(obj, key, val) { const dep = new Dep() Object.defineProperty(obj, key, { writable: true, enumerable: true, get: function getter() { return val }, set: function setter(newVal) { if(val===newVal){ return } val = newVal dep.notify() } })} Watcher123456789class Wacher { constructor() { } update() { }}