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 相关文章推荐
input、button的不同type值在ajax提交表单时导致的陷阱
Feb 24 Javascript
javascript 仿QQ滑动菜单效果代码
Sep 03 Javascript
JavaScript中的apply()方法和call()方法使用介绍
Jul 25 Javascript
javascript之典型高阶函数应用介绍二
Jan 10 Javascript
js隐藏与显示回到顶部按钮及window.onscroll事件应用
Jan 25 Javascript
JQuery记住用户名和密码的具体实现
Apr 04 Javascript
JS实现队列与堆栈的方法
Apr 21 Javascript
jQuery 获取屏幕高度、宽度的简单实现案例
May 17 Javascript
jQuery中的siblings()是什么意思(推荐)
Dec 29 Javascript
解决在Bootstrap模糊框中使用WebUploader的问题
Mar 22 Javascript
vue监听浏览器原生返回按钮,进行路由转跳操作
Sep 09 Javascript
前端vue如何使用高德地图
Nov 05 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生成二维码的几种方式整理及使用实例
2013/06/03 PHP
PHP之APC缓存详细介绍 apc模块安装
2014/01/13 PHP
php分页函数示例代码分享
2014/02/24 PHP
php过滤html标记属性类用法实例
2014/09/23 PHP
详解WordPress中的头像缓存和代理中的缓存更新方法
2016/03/01 PHP
Yii2.0预定义的别名功能小结
2016/07/04 PHP
PHP对象链式操作实现原理分析
2016/10/09 PHP
如何在PHP中使用数组
2020/06/09 PHP
简单实用的js调试logger组件实现代码
2010/11/20 Javascript
初窥JQuery(二)事件机制(2)
2010/12/06 Javascript
点击按钮自动加关注的代码(sina微博/QQ空间/人人网/腾讯微博)
2014/01/02 Javascript
javascript三元运算符用法实例
2015/04/16 Javascript
JavaScript实现图片DIV竖向滑动的方法
2015/04/25 Javascript
原生javascript实现图片无缝滚动效果
2016/02/12 Javascript
D3.js实现直方图的方法详解
2016/09/25 Javascript
AJAX和jQuery动态加载数据的实现方法
2016/12/05 Javascript
详解JS中定时器setInterval和setTImeout的this指向问题
2017/01/06 Javascript
Node连接mysql数据库方法介绍
2017/02/07 Javascript
AngularJS 的$timeout服务示例代码
2017/09/21 Javascript
Node.js中环境变量process.env的一些事详解
2017/10/26 Javascript
d3.js 地铁轨道交通项目实战
2019/11/27 Javascript
小程序卡片切换效果组件wxCardSwiper的实现
2020/02/13 Javascript
python中的迭代和可迭代对象代码示例
2017/12/27 Python
Python+selenium实现截图图片并保存截取的图片
2018/01/05 Python
解决Django layui {{}}冲突的问题
2019/08/29 Python
Win系统PyQt5安装和使用教程
2019/12/25 Python
python实现文法左递归的消除方法
2020/05/22 Python
CSS3中的5个有趣的新技术
2009/04/02 HTML / CSS
CSS3悬停效果案例应用
2012/11/21 HTML / CSS
2015年元旦活动总结
2014/05/09 职场文书
2015年幼儿园学期工作总结
2015/05/22 职场文书
格列夫游记读书笔记
2015/07/01 职场文书
调解协议书范本
2016/03/21 职场文书
python实现批量提取指定文件夹下同类型文件
2021/04/05 Python
在pycharm中无法import所安装的库解决方案
2021/05/31 Python
浅析Django接口版本控制
2021/06/26 Python