1. Vue2 响应式原理-Object.defineProperty

创建一个Vue的Class类
class Vue {
    constructor(options) {
        this.$options = options;  // 接收实例化Vue时的option,绑定到实例上
        this.data = options.data;  // 将实例化Vue时的data绑定到当前实例上
        this.initData();  // 初始化data
    }

    initData() {
        const data = this.data;
        const keys = Object.keys(data); // 取data属性的所有键
        for (let i = 0; i < keys.length; i++) { // 将实例中的data上的属性代理到this上
            const key = keys[i];
            Object.defineProperty(this, key, {
                enumerable: true,
                get: function () {
                    return data[key];
                },
                set: function (newVal) {
                    data[key] = newVal;
                }
            })
        }
        // 深度监听(判断data是否是引用类型,如果是引用类型的数据还需要递归深层次监听)
        observe(data); 
    }
}

function observe(data) {
    const type = Object.prototype.toString.call(data);
    // 引用类型需深度监听
    if (type !== ('[object Object]' || '[object Array]')) { // 如果不是引用类型,代表已经遍历到最深层
        return;
    }
    new Observer(data);  // 如果是引用类型,则需深层次的递归监听
}

class Observer { // 创建一个Observer 实例,用于深层次监听
    constructor(data) {
        this.walk(data);
    }
    walk(data) {
        const keys = Object.keys(data);
        for (let i = 0; i < keys.length; i++) {
            const key = keys[i];
            defineReactive(data, key, data[key]);
        }
    }
}

/*
* @param data 需要监听的对象
* @param key 需要监听的对象的属性
* @param value 需要监听的对象的属性值
*/
function defineReactive(data, key, value) {
    observe(data[key]);
    let val = value;
    Object.defineProperty(data, key, {
        enumerable: true,
        get: function () {
            return val;
        },
        set: function (newVal) {
            if (val === newVal) {
                return;
            }
            val = newVal;
        }
    })
}

watch原理后续更新

最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容