js实现双向数据绑定

js双向绑定几种方法的介绍

使用Object.defineProperty实现简单的js双向绑定
剖析Vue原理&实现双向绑定MVVM
利用 JavaScript 数据绑定实现一个简单的 MVVM 库
几种实现双向绑定的做法
目前几种主流的mvc(vm)框架都实现了单向数据绑定,而我所理解的双向数据绑定无非就是在单向绑定的基础上给可输入元素(input、textare等)添加了change(input)事件,来动态修改model和 view,并没有多高深。所以无需太过介怀是实现的单向或双向绑定。

实现数据绑定的做法有大致如下几种:

  • 发布者-订阅者模式(backbone.js)
  • 脏值检查(angular.js)
  • 数据劫持(vue.js)

发布者-订阅者模式: 一般通过sub, pub的方式实现数据和视图的绑定监听,更新数据方式通常做法是 vm.set('property', value)
,这里有篇文章讲的比较详细,有兴趣可点这里
这种方式现在毕竟太low了,我们更希望通过 vm.property = value
这种方式更新数据,同时自动更新视图,于是有了下面两种方式

脏值检查: angular.js 是通过脏值检测的方式比对数据是否有变更,来决定是否更新视图,最简单的方式就是通过 setInterval() 定时轮询检测数据变动,当然Google不会这么low,angular只有在指定的事件触发时进入脏值检测,大致如下:

DOM事件,譬如用户输入文本,点击按钮等。( ng-click )
XHR响应事件 ( $http )
浏览器Location变更事件 ( $location )
Timer事件( $timeout , $interval )
执行 $digest() 或 $apply()

数据劫持: vue.js 则是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。

实现MVVM

思路整理
已经了解到vue是通过数据劫持的方式来做数据绑定的,其中最核心的方法便是通过Object.defineProperty()
来实现对属性的劫持,达到监听数据变动的目的,无疑这个方法是本文中最重要、最基础的内容之一,如果不熟悉defineProperty,猛戳这里整理了一下,要实现mvvm的双向绑定,就必须要实现以下几点:1、实现一个数据监听器Observer,能够对数据对象的所有属性进行监听,如有变动可拿到最新值并通知订阅者2、实现一个指令解析器Compile,对每个元素节点的指令进行扫描和解析,根据指令模板替换数据,以及绑定相应的更新函数3、实现一个Watcher,作为连接Observer和Compile的桥梁,能够订阅并收到每个属性变动的通知,执行指令绑定的相应回调函数,从而更新视图4、mvvm入口函数,整合以上三者
上述流程如图所示:


具体实现查看链接: https://segmentfault.com/a/1190000006599500

用原生js的defineProperty写一个双向数据绑定

用原生Javascript对象中的访问器属性实现双向数据绑定

var input = document.querySelector("#text");
var data = {};
Object.defineProperty(data, "name", {
  configurable: true,
  get: function(){
      return input.value
  },
  set: function(newValue){
    //this.value = newValue;
    input.value = newValue;
  }
})
data.name = "sss";
input.onchange = function(){
  data.name = data.name;
}

但是当有两个输入框中的值想同时绑定user.name的时候怎么办呢?




var input1 = document.querySelector("#text1");
var input2 = document.querySelector("#text2");
var data = {};
Object.defineProperty(data, "name", {
  configurable: true,
  get: function(){
      console.log(1111);
      return input1.value
  },
  set: function(newValue){
      console.log(222);
    input1.value = newValue;
    input2.value = newValue;
  }
})
data.name = "sss";
input1.onchange = function(){
  console.log(33333)
  data.name = data.name;
}
input2.onchange = function(){
  input1.value = this.value;
  console.log(data);
}

当我改变input2的值的时候。input1的value会发生变化,这是必然的。但是这时候我打印data。data值竟然也更新了。input2.onchange里 并没有调用data的set啊。input1.value发生改变,也并没有触发input1的onchange啊。那 data的数据的更新,到底是怎么触发的啊?

你可能感兴趣的:(js实现双向数据绑定)