vue双向数据绑定原理探究(附demo)
2017-05-08 10:24
941 查看
昨天被导师叫去研究了一下vue的双向数据绑定原理。。。本来以为原理的东西都非常高深,没想到vue的双向绑定真的很好理解啊。。。自己动手写了一个。
传送门
双向绑定的思想
双向数据绑定的思想就是数据层与UI层的同步,数据再两者之间的任一者发生变化时都会同步更新到另一者。
双向绑定的一些方法
目前,前端实现数据双向数据绑定的方法大致有以下三种:
1.发布者-订阅者模式(backbone.js)
思路:使用自定义的data属性在HTML代码中指明绑定。所有绑定起来的JavaScript对象以及DOM元素都将“订阅”一个发布者对象。任何时候如果JavaScript对象或者一个HTML输入字段被侦测到发生了变化,我们将代理事件到发布者-订阅者模式,这会反过来将变化广播并传播到所有绑定的对象和元素。
2.赃值检测(angular.js)
思路:通过轮询的方式检测数据变动。才特定的事件触发时进入赃值检测。
大致如下:
• DOM事件,譬如用户输入文本,点击按钮等。( ng-click )
• XHR响应事件 ( $http )
• 浏览器Location变更事件 ( $location )
• Timer事件( $timeout , $interval )
• 执行 $digest() 或 $apply()
3.数据劫持(vue.js)
思路:使用Object.defineProperty对数据对象做属性get和set的监听,当有数据读取和赋值操作时则调用节点的指令,这样使用最通用的=等号赋值就可以触发了。
wue双向数据绑定小demo思路
① 构造一个Wue对象,定义该对象的属性el、data,创建对象的时候传相应数据,并执行init()方法。
② Init方法中执行bindText和bindModel方法,这两个方法分别是解析dom中绑定了w-model、w-text指令的html,并作相应处理。
③ bindText方法,把带有w-text指令的元素放进一个数组中,如:w-text=’demo’,然后令其innerHTML的值等于传进来的data[demo]。
④ bindModel方法,把带有w-model指令的元素(一般为form相关元素)放进一个数组中,如:w-model=’demo’,为每一个元素绑定keyup事件(兼容浏览器写法)。
⑤ 使用Object.defineProperty,定义set和get方法,并在set方法中调用bindText方法。这是利用了一旦w-model的值在input中被改变,会自动执行set方法,所以只有在这个方法中调用更新w-text的方法即可。
⑥使用
传送门
双向绑定的思想
双向数据绑定的思想就是数据层与UI层的同步,数据再两者之间的任一者发生变化时都会同步更新到另一者。
双向绑定的一些方法
目前,前端实现数据双向数据绑定的方法大致有以下三种:
1.发布者-订阅者模式(backbone.js)
思路:使用自定义的data属性在HTML代码中指明绑定。所有绑定起来的JavaScript对象以及DOM元素都将“订阅”一个发布者对象。任何时候如果JavaScript对象或者一个HTML输入字段被侦测到发生了变化,我们将代理事件到发布者-订阅者模式,这会反过来将变化广播并传播到所有绑定的对象和元素。
2.赃值检测(angular.js)
思路:通过轮询的方式检测数据变动。才特定的事件触发时进入赃值检测。
大致如下:
• DOM事件,譬如用户输入文本,点击按钮等。( ng-click )
• XHR响应事件 ( $http )
• 浏览器Location变更事件 ( $location )
• Timer事件( $timeout , $interval )
• 执行 $digest() 或 $apply()
3.数据劫持(vue.js)
思路:使用Object.defineProperty对数据对象做属性get和set的监听,当有数据读取和赋值操作时则调用节点的指令,这样使用最通用的=等号赋值就可以触发了。
wue双向数据绑定小demo思路
① 构造一个Wue对象,定义该对象的属性el、data,创建对象的时候传相应数据,并执行init()方法。
1 2 3 4 5 | var Wue= function (params){ this .el=document.querySelector(params.el); this .data=params.data; this .init(); }; |
1 2 3 4 | init: function (){ this .bindText(); this .bindModel(); } |
1 2 3 4 5 6 7 8 9 | bindText: function (){ var textDOMs= this .el.querySelectorAll( '[w-text]' ), bindText; for ( var i=0;i<textDOMs.length;i++){ bindText=textDOMs[i].getAttribute( 'w-text' ); textDOMs[i].innerHTML= this .data[bindText]; } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | bindModel: function (){ var modelDOMs= this .el.querySelectorAll( '[w-model]' ), bindModel; var _that= this ; for ( var i=0;i<modelDOMs.length;i++){ bindModel=modelDOMs[i].getAttribute( 'w-model' ); modelDOMs[i].value= this .data[bindModel]|| '' ; //数据劫持 this .defineObj( this .data,bindModel); if (document.addEventListener){ modelDOMs[i].addEventListener( 'keyup' , function (event) { console.log( 'test' ); e=event||window.event; _that.data[bindModel]=e.target.value; }, false ); } else { modelDOMs[i].attachEvent( 'onkeyup' , function (event){ e=event||window.event; _that.data[bindModel]=e.target.value; }, false ); } } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | defineObj: function (obj,prop,value){ var val=value|| '' ; var _that= this ; try { Object.defineProperty(obj,prop,{ get: function (){ return val; }, set: function (newVal){ val=newVal; _that.bindText(); } }) } catch (err){ console.log( 'Browser not support!' ) } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | html:<br><h3>双向数据绑定demo</h3> <div id= "wrap" > <input type= "text" w-model= 'demo' > <h5 w-text= 'demo' ></h5> </div><br>js: <script src= '../js/wue.js' ></script> <script> new Wue({ el: '#wrap' , data:{ demo: 'winty' } }) </script> |
相关文章推荐
- vue双向数据绑定原理探究(附demo)
- vue双向数据绑定原理探究(附demo)
- vue.js双向数据绑定原理解析及模拟demo的实现
- vue双向数据绑定原理
- VUE双向数据绑定原理分析
- vue双向数据绑定的实现原理
- vue.js双向数据绑定实现原理
- Vue实现双向绑定的原理以及响应式数据的方法
- 初探Vue原理之view-model的数据动态双向绑定
- 浅析VUE双向绑定原理,实现数据监听并通知订阅者
- vue 双向数据绑定原理
- Vue.js双向数据绑定原理
- vue数据双向绑定原理解析(get & set)
- Vue双向数据绑定原理解析
- 浅谈vue,angular,react数据双向绑定原理分析
- Vue双向数据绑定原理
- Vue数据双向绑定的原理
- Vue 双向数据绑定原理
- Vue双向数据绑定原理
- Vue 双向数据绑定原理分析