Vue学习之数据监听Observer类实现

Vue学习之数据监听Observer类实现

创建脚本文件

文件名:Observer.js

在index.html中引入脚本文件<script src="Observer.js"></script>

创建Observer类,并在构造函数中传入Vue实例的data数据。

class Observer {
    constructor(data) {
        this.observer(data);
    }
    // 实现数据变化监听
    observer(data) {

    }
}

在MyVue.js中构造Vue实例时初始化Observer类

class MyVue {
    // 构造函数
    constructor(options) {
        this.$el = options.el;
        this.$data = options.data;
        this.$options = options;
        if (this.$el) {
        //-----------------------------------------
            // 实现数据监听类
            new Observer(this.$data);
        //-----------------------------------------
            // 实现指令解析类
            new Compile(this.$el, this);
        }
    }
}

接下来实现对vue中data的数据劫持

    // 实现数据变化监听
    observer(data) {
        console.log(data);
        // 判断数据是否为对象并处理
        if (data && typeof data === 'object') {
            // console.log(Object.keys(data));
            // 利用Object.keys方法取出data的key值
            Object.keys(data).forEach(key => {
                // 定义响应方法 即劫持数据的getter和setter方法
                this.defineReactive(data, key, data[key]);
            })
        }
    }

利用Object.defineProperty方法重新定义data中各个数据的get和set方法。

    /**
     * 
     * @param {object} data vue实例中的data数据
     * @param {string} key 遍历到的key值
     * @param {string} value key值对应的value
     */
    defineReactive(data, key, value) {
        const self = this;
        // 递归遍历 直到value不再为object
        self.observer(value);
        // 劫持并监听所有属性 利用Object.defineProperty重新定义get和set方法
        Object.defineProperty(data, key, {
            enumerable: true,
            configurable: false,
            get() {
                return value;
            },
            set(newVal) {
                // 注意在修改对象值时,要对新值添加监听
                self.observer(newVal)
                if (value !== newVal) {
                    console.log("监听到数据变化:" + key + " 由 " + value + " 变成 " + newVal);
                    value = newVal;
                }
            }
        })
    }

至此,完成了对数据的劫持监听,在console修改data中的数据时,可以看到监听输出。

vm.$data.htmlStr="33333"               Observer.js:7 
33333                                  Observer.js:39 
监听到数据变化:htmlStr 由 <h4>还喜欢和大家一起学习。</h4> 变成 33333

接下来将实现Vue中的wathcer,从而实现视图驱动数据变化。

demo地址:Demo

上一篇:使用Intersection Observer接口实现可视区域渲染


下一篇:观察者模式-行为型