Vue原理学习(二)

2018-05-13  本文已影响64人  IsaacHHH

响应式系统的基本原理

Vue基于Object.defineProperty来实现响应式,对于Object.defineProperty大家就算不熟悉也听说过,我之前的文章也详细介绍过。

语法大家参考文档即可。

在上次的Vue原理学习(一)中,我们画了一张图,其中有一个_init的过程,也就是new Vue之后。

_init的过程,会对数据进行响应式的处理。

我们先来看看代码:

function defineDispose(obj, key, val) {
    Object.defineProperty(obj, key, {
      enumerable: true, // 可枚举
      configurable: true, // 可配置、可重写
      get: function() {
        return val; // 返回value,在这里Vue会产生依赖收集
      },
      set: function(newVal) {
        if(newVal === val) return
        cb(newVal)
      }
    })
}

这里我们用一个函数对Object.property进行了简单的封装,并且在set的时候,调用了一个cb函数。

// cb函数
function cb (newVal) {
    console.log('数据发生了更新: ' + newVal);
}

到这里,虽然代码可以正常工作,但是依然是不够的,我们需要在封装一层observer。传入一个value,也就是需要响应式的对象,在通俗点说,就是new Vue()的时候, 传入的那个参数对象。

function observer(value) {
    Object.keys(value).forEach(key => {
        // 调用defineDispose函数
        defineDispose(value, key, value[key]);
    })
} 

这里,我们使用遍历来对每个对象属性进行了Object.defineProperty处理,也就是响应式处理,当然,这个实际的过程会复杂很多,比如需要对数据类型判断、算法处理等等。

最后,我们实现可以通过new Vue的方式来初始化对象:

class Vue{
    // 构造函数
    constructor(options) {
         this._data = options.data; // 只对data处理
         observer(this._data); // 调用observer
    }
}

最后我们来调用一下:

let vue = new Vue({
    data: {
        title: '中国第一艘国产航母13日清晨离开码头 开始海试'
    }
});
// 更新数据
vue._data.title = '中超-恒大2-2华夏近4场不胜 鲁能压哨平权健';
// 此时会调用cb函数打印如下数据: 
// 数据发生了更新: 中超-恒大2-2华夏近4场不胜 鲁能压哨平权健  

这里,我们对Vue的响应式有了一个基本的认识,整个过程也为我们复习了Object.defineProperty。当然,实际的过程会比这复杂的多。

在刚才的代码中,我们发现,必须使用_data的改变才可以,但是Vue中却可以直接使用this.xxx,实际上Vue本质也是 _data,只不过是使用了数据代理,将_data代理到了data上。

嗯嗯嗯嗯嗯。

以上笔记是我 阅读 掘金小册 所得。
链接:https://juejin.im/book/5a36661851882538e2259c0f?inviteCode=596197525188257fd215e23e

上一篇下一篇

猜你喜欢

热点阅读