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 相关文章推荐
对YUI扩展的Gird组件 Part-1
Mar 10 Javascript
Zero Clipboard js+swf实现的复制功能使用方法
Mar 07 Javascript
JQuery 1.3.2以上版本中出现pareseerror错误的解决方法
Jan 11 Javascript
js限制文本框输入长度两种限制方式(长度、字节数)
Dec 19 Javascript
web网页按比例显示图片实现原理及js代码
Aug 09 Javascript
让input框实现类似百度的搜索提示(基于jquery事件监听)
Jan 31 Javascript
js调试工具console.log()方法查看js代码的执行情况
Aug 08 Javascript
javascript文本框内输入文字倒计数的方法
Feb 24 Javascript
AngularJS 中使用Swiper制作滚动图不能滑动的解决方法
Nov 15 Javascript
Bootstrap table右键功能实现方法
Feb 20 Javascript
js实现登录注册框手机号和验证码校验(前端部分)
Sep 28 Javascript
详解a标签添加onclick事件的几种方式
Mar 29 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
Protoss兵种介绍
2020/03/14 星际争霸
php 变量定义方法
2009/06/14 PHP
php生成的html meta和link标记在body标签里 顶部有个空行
2010/05/18 PHP
php实现信用卡校验位算法THE LUHN MOD-10示例
2014/05/07 PHP
使用array_map简单搞定PHP删除文件、删除目录
2014/10/29 PHP
细说浏览器特性检测(2)-通用事件检测
2010/11/05 Javascript
setInterval()和setTimeout()的用法和区别示例介绍
2013/11/17 Javascript
jQuery中remove()方法用法实例
2014/12/25 Javascript
JQuery radio(单选按钮)操作方法汇总
2015/04/15 Javascript
js控制li的隐藏和显示实例代码
2016/10/15 Javascript
Bootstrap基本模板的使用和理解1
2016/12/14 Javascript
微信小程序 常用工具类详解及实例
2017/02/15 Javascript
Vue.js实现一个todo-list的上移下移删除功能
2017/06/26 Javascript
快速解决angularJS中用post方法时后台拿不到值的问题
2018/08/14 Javascript
JS加密插件CryptoJS实现的Base64加密示例
2020/08/16 Javascript
NodeJS加密解密及node-rsa加密解密用法详解
2018/10/12 NodeJs
javascript面向对象创建对象的方式小结
2019/07/29 Javascript
layui的数据表格+springmvc实现搜索功能的例子
2019/09/28 Javascript
黑科技 Python脚本帮你找出微信上删除你好友的人
2016/01/07 Python
python中selenium操作下拉滚动条的几种方法汇总
2019/07/14 Python
Python全栈之列表数据类型详解
2019/10/01 Python
JupyterNotebook设置Python环境的方法步骤
2019/12/03 Python
Python API len函数操作过程解析
2020/03/05 Python
python 服务器运行代码报错ModuleNotFoundError的解决办法
2020/09/16 Python
基于python实现坦克大战游戏
2020/10/27 Python
python opencv实现直线检测并测出倾斜角度(附源码+注释)
2020/12/31 Python
CSS3 filter(滤镜)实现网页灰色或者黑色模式的代码
2020/11/30 HTML / CSS
美国第二大团购网站:LivingSocial
2016/07/24 全球购物
英国最大的独立家具零售商:Furniture Village
2016/09/06 全球购物
VIVOBAREFOOT赤脚鞋:让您的脚做自然的事情
2017/06/01 全球购物
高中学生干部学习的自我评价
2014/02/21 职场文书
企业宣传口号
2014/06/12 职场文书
新兵入伍心得体会
2014/09/04 职场文书
写给老师的保证书
2015/05/09 职场文书
餐馆开业致辞
2015/08/01 职场文书
2016年八一建军节活动总结
2016/04/05 职场文书