vue双向数据绑定原理探究(附demo)

网友投稿 214 2023-06-17


vue双向数据绑定原理探究(附demo)

昨天被导师叫去研究了一下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()方法。

var Wue=function(params){

this.el=document.querySelector(params.el);

this.data=params.data;

this.init();

};

②  Init方法中执行bindText和bindModel方法,这两个方法分别是解析dom中绑定了w-model、w-text指令的html,并作相应处理。

init:function(){

this.bindText();

this.bindModel();

}

③  bindText方法,把带有w-text指令的元素放进一个数组中,如:w-text='demo',然后令其innerHTML的值等于传进来的data[demo]。

bindText:function(){

var textDOMs=this.el.querySelectorAll('[w-text]'),

bindText;

for(var i=0;i

bindText=textDOMs[i].getAttribute('w-text');

textDOMs[i].innerHTML=this.data[bindText];

}

}

④  bindModel方法,把带有w-model指令的元素(一般为form相关元素)放进一个数组中,如:w-model='demo',为每一个元素绑定keyup事件(兼容浏览器写法)。

bindModel:function(){

var modelDOMs=this.el.querySelectorAll('[w-model]'),

bindModel;

var _that=this;

for(var i=0;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);

}

}

}

⑤  使用Object.defineProperty,定义set和get方法,并在set方法中调用bindText方法。这是利用了一旦w-model的值在input中被改变,会自动执行set方法,所以只有在这个方法中调用更新w-text的方法即可。

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.bihttp://ndText();

}

})

}catch (err){

console.log('Browser not support!')

}

}

⑥使用

html:

双向数据绑定demo


js:

bindText=textDOMs[i].getAttribute('w-text');

textDOMs[i].innerHTML=this.data[bindText];

}

}

④  bindModel方法,把带有w-model指令的元素(一般为form相关元素)放进一个数组中,如:w-model='demo',为每一个元素绑定keyup事件(兼容浏览器写法)。

bindModel:function(){

var modelDOMs=this.el.querySelectorAll('[w-model]'),

bindModel;

var _that=this;

for(var i=0;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);

}

}

}

⑤  使用Object.defineProperty,定义set和get方法,并在set方法中调用bindText方法。这是利用了一旦w-model的值在input中被改变,会自动执行set方法,所以只有在这个方法中调用更新w-text的方法即可。

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.bihttp://ndText();

}

})

}catch (err){

console.log('Browser not support!')

}

}

⑥使用

html:

双向数据绑定demo

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);

}

}

}

⑤  使用Object.defineProperty,定义set和get方法,并在set方法中调用bindText方法。这是利用了一旦w-model的值在input中被改变,会自动执行set方法,所以只有在这个方法中调用更新w-text的方法即可。

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.bihttp://ndText();

}

})

}catch (err){

console.log('Browser not support!')

}

}

⑥使用

html:

&lhttp://t;script src='../js/wue.js'>

完整demo下载:https://github.com/LuckyWinty/two-way-data


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:java集合 collection
下一篇:微信小程序实现图片预加载组件
相关文章

 发表评论

暂时没有评论,来抢沙发吧~