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


Posted in Javascript onJanuary 17, 2017

昨天被导师叫去研究了一下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<textDOMs.length;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<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);
 }
 } 
}

⑤  使用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.bindText();
  }
  })
 
  }catch (err){
  console.log('Browser not support!')
  } 
 }

⑥使用

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>

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

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持三水点靠木!

Javascript 相关文章推荐
jQuery 选择器、DOM操作、事件、动画
Nov 25 Javascript
jQuery创建DOM元素实例解析
Jan 19 Javascript
JavaScript动态生成二维码图片
Apr 20 Javascript
javascript中的后退和刷新实现方法
Nov 10 Javascript
浅谈Node.js轻量级Web框架Express4.x使用指南
May 03 Javascript
详解Web使用webpack构建前端项目
Sep 23 Javascript
JavaScript生成简单等差数列
Nov 28 Javascript
jQuery分组选择器简单用法示例
Apr 04 jQuery
vue本地打开build后生成的dist文件夹index.html问题
Sep 04 Javascript
JavaScript多种滤镜算法实现代码实例
Dec 10 Javascript
基于vue-draggable 实现三级拖动排序效果
Jan 10 Javascript
Vue移动端用淘宝弹性布局lib-flexible插件做适配的方法
May 26 Javascript
JavaScript中英文字符长度统计方法示例【按照中文占2个字符】
Jan 17 #Javascript
浅析vue数据绑定
Jan 17 #Javascript
JavaScript使用正则表达式获取全部分组内容的方法示例
Jan 17 #Javascript
JavaScript使用delete删除数组元素用法示例【数组长度不变】
Jan 17 #Javascript
微信小程序 缓存(本地缓存、异步缓存、同步缓存)详解
Jan 17 #Javascript
详谈JavaScript的闭包及应用
Jan 17 #Javascript
用原生js做单页应用
Jan 17 #Javascript
You might like
php中通过Ajax如何实现异步文件上传的代码实例
2011/05/07 PHP
APACHE的AcceptPathInfo指令使用介绍
2013/01/18 PHP
php 问卷调查结果统计
2015/10/08 PHP
PHP实现的一致性哈希算法完整实例
2015/11/14 PHP
PHP对象克隆clone用法示例
2016/09/28 PHP
PHP开发APP端微信支付功能
2017/02/17 PHP
PHP实现的redis主从数据库状态检测功能示例
2017/07/20 PHP
PHP实现类似于C语言的文件读取及解析功能
2017/09/01 PHP
validator验证控件使用代码
2010/11/23 Javascript
工作需要写的一个js拖拽组件
2011/07/28 Javascript
深入理解JavaScript系列(9) 根本没有“JSON对象”这回事!
2012/01/15 Javascript
P3P Header解决Cookie跨域的问题
2013/03/12 Javascript
Javascript毫秒数用法实例
2015/02/05 Javascript
javascript 闭包详解
2015/07/02 Javascript
浅谈Node.js:fs文件系统模块
2016/12/08 Javascript
Bootstrap CSS组件之按钮组(btn-group)
2016/12/17 Javascript
微信小程序scroll-view实现横向滚动和上拉加载示例
2017/03/06 Javascript
微信小程序开发之toast提示插件使用示例
2017/06/08 Javascript
VUE 实现滚动监听 导航栏置顶的方法
2018/09/11 Javascript
详解JavaScript中typeof与instanceof用法
2018/10/24 Javascript
深入理解es6块级作用域的使用
2019/03/28 Javascript
微信小程序scroll-view点击项自动居中效果的实现
2020/03/25 Javascript
Vue 中使用lodash对事件进行防抖和节流操作
2020/07/26 Javascript
基于Vue中的父子传值问题解决
2020/07/27 Javascript
[02:17]2016国际邀请赛中国区预选赛VG战队领队采访
2016/06/26 DOTA
python网络编程之数据传输UDP实例分析
2015/05/20 Python
python跳过第一行快速读取文件内容的实例
2018/07/12 Python
Python3内置模块之base64编解码方法详解
2019/07/13 Python
解决Python对齐文本字符串问题
2019/08/28 Python
python pygame实现球球大作战
2019/11/25 Python
Html5基于canvas实现电子签名并生成PDF文档
2020/12/07 HTML / CSS
JBL澳大利亚官方商店:扬声器、耳机和音响系统
2018/05/24 全球购物
大学生毕业自我评价范文分享
2013/11/07 职场文书
中华魂演讲稿
2014/05/13 职场文书
优秀应届生求职信
2014/06/16 职场文书
奖学金感谢信
2015/01/21 职场文书