① 响应式系统的基本原理

1 Object.defineProperty

Vue.js基于 Object.defineProperty 实现响应式系统

使用方法:

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

descriptor 的属性

  • enumberable: 属性是否可枚举,默认 false
  • configurable: 属性是否可被修改|删除,默认 false
  • get: 获取属性的方法
  • set: 设置属性的方法

2 实现 observer(可观察的)

简化过程:不考虑数组等复杂情况,只处理对象

1. 定义函数 cb

模拟视图更新,调用 cb 即代表更新视图

function cb (val) {
    // 渲染视图
    console.log('视图更新啦~');
}

2. 定义 defineReactive 函数

defineReactive 函数通过 Object.defineProperty 来实现对对象的响应式化

入参

  • obj 需要绑定的对象
  • key obj的某一个属性
  • val 具体的值

经过 defineReactive 处理后

  • obj 的 key 属性在 时会触发 reactiveGetter 方法
  • 该属性被 时会触发 reactiveSetter 方法
function defineReactive (obj, key, val) {
    Object.defineProperty(obj, key, {
        enumberable: true,
        configurable: true,
        get: function reactiveGetter () {
            return val; // 实际上会收集依赖
        },
        set: function reactiveSetter (newVal) {
            if (newVal === val) return;
            val = newVal;
            cb(newVal);
        } 
    })
}

3. 封装一层 observer

传入一个 value(需要响应式化的对象),通过遍历所有属性的方式对该对象的每一个属性都通过 defineReactive 处理

实际上 Observer 会进行递归调用

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

3 封装 Vue

1. 构造函数

在 Vue 的构造函数中,对 optionsdata 进行处理,这里的 data 就是 Vue 实例中的 data 属性

data 实际上是一个函数,这里当作一个对象简单处理

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

2. new Vue

new 一个 Vue 对象时,就会将 data 中的数据进行响应式化

改变 data 属性值,就会触发 cb 方法更新视图

let o = new Vue({
    data: {
        test: 'I am test.'
    }
});
o._data.test = 'Hello world'; // 视图更新啦~
posted on 2021-01-26 16:33  pleaseAnswer  阅读(206)  评论(0编辑  收藏  举报