关于数据的双向绑定

本文探讨了Backbone.js、Angular.js及Vue.js三种不同MVVM框架的数据绑定机制。Backbone.js采用发布者-订阅者模式,Angular.js利用脏值检查机制,而Vue.js则通过数据劫持结合发布者-订阅者模式实现数据与视图的双向绑定。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

实现数据绑定的做法:
backbone.js(发布者-订阅者模式)
一般通过sub, pub的方式实现数据和视图的绑定监听
1.识别ui属性
2.监听属性变化
3.将变化传播出来
我们可以使用自定义的data属性在HTML代码中指明绑定。所有绑定起来的JavaScript对象以及DOM元素都将“订阅”一个发布者对象。任何时候如果JavaScript对象或者一个HTML输入字段被侦测到发生了变化,我们将代理事件到发布者-订阅者模式,这会反过来将变化广播并传播到所有绑定的对象和元素。

angular.js(脏值检查)

angular脏值检查实在指定的事件被触发时进入数据对比,之后决定是否更新视图,触发一般有
  1. DOM事件,譬如用户输入文本,点击按钮等。( ng-click )
  2. XHR响应事件 ( $http )
  3. 浏览器Location变更事件 ( $location )
  4. Timer事件( timeout,interval )
  5. 执行 digest()apply()

vue(数据劫持)
vue.js 则是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来get,和set在数据变动时发布消息给订阅者,触发相应的监听回调,vue对应的函数是defineReactive$$1

/**
 * Define a reactive property on an Object.
 */
function defineReactive$$1 (
  obj,
  key,
  val,
  customSetter,
  shallow
) {
  var dep = new Dep();

  var property = Object.getOwnPropertyDescriptor(obj, key);
  if (property && property.configurable === false) {
    return
  }

  // cater for pre-defined getter/setters
  var getter = property && property.get;
  var setter = property && property.set;

  var childOb = !shallow && observe(val);
  Object.defineProperty(obj, key, {
    enumerable: true,
    configurable: true,
    get: function reactiveGetter () {
      var value = getter ? getter.call(obj) : val;
      if (Dep.target) {
        dep.depend();
        if (childOb) {
          childOb.dep.depend();
        }
        if (Array.isArray(value)) {
          dependArray(value);
        }
      }
      return value
    },
    set: function reactiveSetter (newVal) {
      var value = getter ? getter.call(obj) : val;
      /* eslint-disable no-self-compare */
      if (newVal === value || (newVal !== newVal && value !== value)) {
        return
      }
      /* eslint-enable no-self-compare */
      if ("development" !== 'production' && customSetter) {
        customSetter();
      }
      if (setter) {
        setter.call(obj, newVal);
      } else {
        val = newVal;
      }
      childOb = !shallow && observe(newVal);
      dep.notify();
    }
  });
}

在数据读取时,数据的观察者Watcher会根据数据的变化来更新数据到模板上,其中dep关联当前Watcher的所有的依赖,根据Watcher分发所有的变动,然后各自处理。

这里写图片描述

在vue编译的时候compile这一层识别所有的目标元素,并在link这一阶段一一对应的建立一个数据关系,并开始初始渲染
1、实现一个数据监听器Observer,能够对数据对象的所有属性进行监听,如有变动可拿到最新值并通知订阅者
2、实现一个指令解析器Compile,对每个元素节点的指令进行扫描和解析,根据指令模板替换数据,以及绑定相应的更新函数
3、实现一个Watcher,作为连接Observer和Compile的桥梁,能够订阅并收到每个属性变动的通知,执行指令绑定的相应回调函数,从而更新视图
4、mvvm入口函数,整合以上三者

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值