双向数据绑定

不过在不同的 MVVM 框架中,实现双向数据绑定的技术有所不同。

AngularJS 采用“脏值检测”的方式,数据发生变更后,对于所有的数据和视图的绑定关系进行一次检测,识别是否有数据发生了改变,有变化进行处理,可能进一步引发其他数据的改变,所以这个过程可能会循环几次,一直到不再有数据变化发生后,将变更的数据发送到视图,更新页面展现。如果是手动对 ViewModel 的数据进行变更,为确保变更同步到视图,需要手动触发一次“脏值检测”。

VueJS 则使用 ES5 提供的 Object.defineProperty() 方法,监控对数据的操作,从而可以自动触发数据同步。并且,由于是在不同的数据上触发同步,可以精确的将变更发送给绑定的视图,而不是对所有的数据都执行一次检测。

Object.defineProperty() 定义的数据 set、get 函数中。Vue 中对于的函数为 defineReactive,基本特性如下:

function defineReactive(obj, key, value) {
    var dep = new Dep()
    Object.defineProperty(obj, key, {
        enumerable: true,
        configurable: true,
        get: function reactiveGetter() {
            if (Dep.target) {
                dep.depend()
            }
            return value
        },
        set: function reactiveSetter(newVal) {
            if (value === newVal) {
                return
            } else {
                value = newVal
                dep.notify()
            }
        }
    })
}

先看官网上的一张图(来自:https://vuefe.cn/v2/guide/reactivity.html):

data.png

主要分为四部分:

  1. Data:也就是数据属性观察者(observer),它劫持属性变化,并负责
    • 添加订阅者(watcher)到订阅者容器(Dependency)
    • 数据改变时,通知订阅者容器发布更新通知。
  2. Dependency:一个订阅者容器,负责维护watcher,并通知watcher做更新操作。
  3. Watcher:某个属性数据的监听者/订阅者,一旦数据有变化,它会通知指令(directive)重新编译模板并渲染UI。
  4. Directive(Component Render Function):指令负责将model和DOM关联起来,在watcher触发下,它可以根据最新的数据重新编译模板,并最终重绘UI(vue2.0在重绘DOM时,采用虚拟DOM树机制,用最小的开销更新UI)。

下面是一张更加详细的剖析图(图内的方法名只作为示例):

vue-data.png

参考:数据绑定精简源码分析

results matching ""

    No results matching ""