响应式系统的基本原理

响应式系统

Vue.js是一款MVVM框架,数据模型仅仅是普通的JavaScript对象,但是对象的操作能影响视图,其核心就是响应式系统。

Object.defineProperty

使用方法:

/*
    obj: 目标对象
    prop: 需要操作的目标对象的属性名
    descriptor: 描述符    
    return value 传入对象
*/
Object.defineProperty(obj, prop, descriptor)

descriptor的一些属性

  • enumerable 属性是否可以枚举 默认false
  • configurable 属性是否可以被修改 默认false
  • get 获取属性的方法
  • set 设置属性的方法

实现observe(可观察的)

首先我们定义一个简单的view函数,这个函数用来模拟视图更新。

function view(val) {
    // TODO 渲染视图
    console.log('视图更新了');
}

Vue.js中源代码是通过定义一个defineReactive方法对Object.defineProperty进行封装了。

function defineReactive(data, key, val) {
    Object.defineProperty(data, key, {
        enumerable: true,
        configurable: true,
        get: function () {
            return val;
        },
        set: function (newVal) {
            if (val === newVal){
                return;
            }
            val = newVal;
        }
    })
}

我们在上面在封装一个observer,它可以对一个对象的所有属性及子属性都转化为可侦测的。此处我们暂时只做第一层的侦测,多层的侦测可以通过在defineReacticve中判断typeof 为 object 时候继续调用observer,具体可以参考 object的变化侦测

function observer(value) {
   if (!value || (typeof value !== 'object')) {
        return;
    }
    Object.keys(value).forEach((key) => {
        defineReactive(value, key, value[key]);
    });
}

在 Vue 的构造函数中,对 options 的 data 进行处理,这里的 data 想必大家很熟悉,就是平时我们在写 Vue 项目时组件中的 data 属性(实际上是一个函数,这里当作一个对象来简单处理)。

class Vue {
    /* Vue构造类 */
    constructor(options) {
        this._data = options.data;
        observer(this._data);
    }
}

这样我们只要 new 一个 Vue 对象,就会将 data 中的数据进行「响应式」化。如果我们对 data 的属性进行下面的操作,就会触发 cb 方法更新视图。

let o = new Vue({
    data: {
        test: "I am test."
    }
});
o._data.test = "hello,world.";  // 视图更新了

你可能感兴趣的:(响应式系统的基本原理)