vue 源码分析-数据驱动视图

vue 是数据驱动视图的框架,简单来说就是数据发生变化,调用vue 的 render 方法,返回视图,显示在浏览器上;

如何知道数据发生变化?

  做到数据每次的读和写的操作都可以监测,vue 2.0 是用了 Object.defineProperty 方法,方法接收3个参数,

    1. 原始对象

    2. 原始对象上,需要监听的属性(字符串)

    3. 该属性的一些配置,能否删除,是否可以枚举,是否可写,还有get、set方法 等等(对象)

  其中 get set 就是vue实现数据监测的关键:

    get 每次 获取值,都会调用该方法,可以对返回值进行处理;

    set 每次改变值,都进入该方法,可以拦截修改;

数据变化,如何通知视图更新?

  数据变化,不可能把这个视图都遍历,vue的做法是给某一个监测对象新建一个依赖数据,那个谁用到这个数据,就将谁放到数组中,当数据发生变化,就把每一个依赖通知一遍;

  何时收集依赖?谁用到某一个监测数据,那么就会调用get方法,在这个方法收集依赖;

  何时通知更新?监测数据改变,会调用set方法,在该方法可以通知依赖数据发生变化;

把依赖收集到哪里?

  vue 有一个依赖管理器Dep类,dep类有一个subs的数组,用于存放依赖;还包含一些基本的操作,添加依赖depend、删除依赖removeSub、通知所有依赖更新notify;

依赖到底是谁?

  Vue中还实现了一个叫做Watcher的类,而Watcher类的实例就是我们上面所说的那个"谁"。

  谁用到了数据,谁就是依赖,我们就为谁创建一个Watcher实例。

  数据变化时,我们不直接去通知依赖更新,而是通知依赖对应的Watch实例,由Watcher实例去通知真正的视图。

不足之处

object数据里添加一对新的key/value或删除一对已有的key/value时,它是无法观测到的,导致当我们对object数据添加或删除值时,无法通知依赖,无法驱动视图进行响应式更新。

Vue也注意到了这一点,为了解决这一问题,Vue增加了两个全局API:Vue.setVue.delete

总结:

通过Object.defineProperty方法实现了对object数据的可观测,并且封装了Observer类,让我们能够方便的把object数据中的所有属性(包括子属性)都转换成getter/seter的形式来侦测变化。

接着,我们学习了什么是依赖收集?并且知道了在getter中收集依赖,在setter中通知依赖更新,以及封装了依赖管理器Dep,用于存储收集到的依赖。

最后,我们为每一个依赖都创建了一个Watcher实例,当数据发生变化时,通知Watcher实例,由Watcher实例去做真实的更新操作。

 

其整个流程大致如下:

    1. Data通过observer转换成了getter/setter的形式来追踪变化。
    2. 当外界通过Watcher读取数据时,会触发getter从而将Watcher添加到依赖中。
    3. 当数据发生了变化时,会触发setter,从而向Dep中的依赖(即Watcher)发送通知。
    4. Watcher接收到通知后,会向外界发送通知,变化通知到外界后可能会触发视图更新,也有可能触发用户的某个回调函数等。

猜你喜欢

转载自www.cnblogs.com/vs1435/p/12956257.html
今日推荐