重读vue的MVVM

vue双向数据绑定vue

watcher怎么连接observe和compile?express

observe

* a.经过Object.defineProperty属性拿到数据的getter和setter方法;[存取器]。
对象的属性有任何赋值都会促发get方法。 发出一个消息, 订阅这个消息订阅者促发回掉;
* b.为全部数据添加监听器dep。

getter方法的时候,判断存不存在dep.target,若是存在,就将dep.target添加到dep.addsub;
setter方法的时候,调用dep.notify(),遍历dep里面的订阅者,而且执行update方法; 消息订阅器bash

export default class Dep {
        constructor() {
            this.subs = [];
        };
        addSub(sub) {
            this.subs.push(sub);
        };
        notify() {
            this.subs.forEach(sub => sub.update());
        }
}
复制代码

watch:

Dep.target = this; // 将当前订阅者指向本身
var value = this.vm[exp]; //
触发getter,添加本身到属性订阅器中
Dep.target = null; // 添加完毕,重置
return value; 代码:
export default class Watcher {
    constructor(vm, expOrFn, cb) {
        this.cb = cb
        this.vm = vm
            //此处简化.要区分fuction仍是expression,只考虑最简单的expression
        this.expOrFn = expOrFn
        this.value = this.get()
    }
    update() {
        this.run()
    }
    run() {
        const value = this.get()
        if (value !== this.value) {
            this.value = value
            this.cb.call(this.vm)
        }
    }
    get() {
        Dep.target = this
            //此处简化。。要区分fuction仍是expression
        const value = this.vm._data[this.expOrFn]
        Dep.target = null
        return value
    }
}
复制代码

compile

主要作的事情是解析模板指令,将模板中的变量替换成数据,而后初始化渲染页面视图,并将每一个指令对应的节点绑定更新函数,添加监听数据的订阅者,一旦数据有变更,收到通知,更新视图,如图所示:

监听数据、绑定更新函数的处理是在compileUtil.bind()这个方法中,经过new Watcher()添加回调来接收数据变化的通知
相关文章
相关标签/搜索