深入浅出Vue基于“依赖收集”的响应式原理

2018-01-25  本文已影响38人  peng凯

Vue.js 是一款 MVVM 框架,数据模型仅仅是普通的 JavaScript 对象,但是对这些对象进行操作时,却能影响对应视图,它的核心实现就是响应式系统

Object.defineProperty 
        vue.js 的响应式系统是基于它实现的!    Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象。

Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象。
            参数:Obj 要在其定义属性的对象    

                        prop:要定义或修改的属性名称

                        descriptor : 将被定义或修改的属性描述符

描述:

该方法允许精确添加或修改对象的属性。通过赋值来添加的普通属性会创建在属性枚举期间显示的属性(for...inObject.keys方法), 这些值可以被改变,也可以被删除。这种方法允许这些额外的细节从默认值改变。默认情况下,使用Object.defineProperty()添加的属性值是不可变的。

属性描述符:
        enumerable,属性是否可枚举,默认 false。

        configurable,属性是否可以被修改或者删除,默认 false。

        get,获取属性的方法。

        set,设置属性的方法。

使数据对象变得“可观测( observer )

我们定义一个数据对象,就以王者荣耀里面的其中一个英雄(我最爱的夏侯惇,一把刀切死,尴尬段位还是在铂金。。。。。。)

回归正题:

const hero = {

      health: 3000,

          IQ: 150

}

我们可以直接读写这个英雄的属性!但是我们并不知情!如何让夏侯惇直接告诉我们呢!这时候需要借助Object.defineProperty() 超级兵的帮助!

以上只是生命值health 和 IQ可以观测 !为了把英雄的所有属性可以实现观测
  

让我们用 observer 来封装一个 Vue 吧!

观察者 Watcher

            现在,英雄已经变得可观测,任何的读写操作他都会主动告诉我们,但也仅此而已,我们仍然不知道他是谁。如果我们希望在修改英雄的生命值和IQ之后,他能够主动告诉他的其他信息,这应该怎样才能办到呢?假设可以这样

        我们定义了一个watcher作为“监听器”,它监听了hero的type属性。这个type属性的值取决于hero.health,换句话来说,当hero.health发生变化时,hero.type也应该发生变化,前者是后者的依赖。我们可以把这个hero.type称为“计算属性”。

那么,我们应该怎样才能正确构造这个监听器呢?可以看到,在设想当中,监听器接收三个参数,分别是被监听的对象、被监听的属性以及回调函数,回调函数返回一个该被监听属性的值。顺着这个思路,我们尝试着编写一段代码:

我们现在是通过手动读取hero.type来获取这个英雄的类型,并不是他主动告诉我们的。如果我们希望让英雄能够在health属性被修改后,第一时间主动发起通知,又该怎么做呢


为什么要依赖收集?

        先举个栗子🌰

假如你修改了kai3=121;  但是视图中并没有用但  watcher 就不会更新视图

假如说实例了两个vm1  vm2   改变的是name的值后  你得知道是谁,那两个地方要修改  因此有依赖收集

上一篇下一篇

猜你喜欢

热点阅读