class Vue {
constructor(options) {
this.$options = options
this._data = options.data
// proxy所有的data属性
Object.keys(options.data).forEach(key => this._proxy(key))
// 递归的为数据定义get和set
observer(options.data)
// 通过调用render进行依赖收集,从而将_render方到相关data属性的watcher队列中 (1)
const vdom = watch(this, this._render.bind(this), this._update.bind(this))
console.log(vdom)
}
......
}
function watch(vm, exp, cb) {
Dep.target = cb // (2) _update赋给Dep.target,render函数相关的属性的get方法里会将_update放到其观察者列表里
return exp() // (3) 执行_render,一方面返回虚拟DOM。另一方面,会导致render函数里的vue.$data的属性被访问,从而触发get方法
}
_update() {
console.log("我需要更新");
const vdom = this._render.call(this)
console.log(vdom);
}
_render() {
return this.$options.render.call(this) // render里会访问一些变量,触发这些变量的get,返回的是虚拟dom
}
function defineReactive(obj, key, val, cb) {
const dep = new Dep()
Object.defineProperty(obj, key, {
enumerable: true,
configurable: true,
get: ()=> {
if(Dep.target){
dep.add(Dep.target) // 被访问的变量的get被触发,则render方法会被加入该变量的watch队列。强无敌!!!!
}
return val
},
set: newVal => {
if(newVal === val)
return
val = newVal
dep.notify()
}
})
}
Last active
November 2, 2016 09:30
-
-
Save njleonzhang/0b6a0bfe00b069e9a7a3300051bfdeb9 to your computer and use it in GitHub Desktop.
Vue 2.0 reactive principle
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment