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 相关文章推荐
JavaScript 学习小结(适合新手参考)
Jul 30 Javascript
firefox事件处理之自动查找event的函数(用于onclick=foo())
Aug 05 Javascript
从阶乘函数对比Javascript和C#的异同
May 31 Javascript
Jquery实现鼠标移上弹出提示框、移出消失思路及代码
May 19 Javascript
JQuery处理json与ajax返回JSON实例代码
Jan 03 Javascript
jQuery实现表格展开与折叠的方法
May 04 Javascript
javascript中使用未定义变量或值的情况分析
Jul 19 Javascript
浅谈regExp的test方法取得的值变化的原因及处理方法
Mar 01 Javascript
javascript 开发之网页兼容各种浏览器
Sep 28 Javascript
微信小程序实现下载进度条的方法
Dec 08 Javascript
小程序跳转H5页面的方法步骤
Mar 06 Javascript
Vue之封装公用变量以及实现方式
Jul 31 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对网站验证码进行破解
2015/09/17 PHP
Docker搭建自己的PHP开发环境
2018/02/24 PHP
ThinkPHP3.2框架自定义配置和加载用法示例
2018/06/14 PHP
PHP利用curl发送HTTP请求的实例代码
2020/07/09 PHP
类之Prototype.js学习
2007/06/13 Javascript
Jquery插件之打造自定义的select标签
2011/11/30 Javascript
jquery 日期控件datepicker属性详细解析
2013/11/08 Javascript
了不起的node.js读书笔记之例程分析
2014/12/22 Javascript
JS实现新浪博客左侧的Blog管理菜单效果代码
2015/10/22 Javascript
Eclipse编辑jsp、js文件时卡死现象的解决办法汇总
2016/02/02 Javascript
微信小程序之小豆瓣图书实例
2016/11/30 Javascript
使用grunt合并压缩js和css文件的方法
2017/03/02 Javascript
AngularJs导出数据到Excel的示例代码
2017/08/11 Javascript
JS实现div模块的截图并下载功能
2017/10/17 Javascript
你可能不知道的前端算法之文字避让(inMap)
2018/01/12 Javascript
详解Vue.js v-for不支持IE9的解决方法
2018/12/29 Javascript
vue配置多代理服务接口地址操作
2020/09/08 Javascript
R vs. Python 数据分析中谁与争锋?
2017/10/18 Python
python 将数据保存为excel的xls格式(实例讲解)
2018/05/03 Python
Python推导式简单示例【列表推导式、字典推导式与集合推导式】
2018/12/04 Python
Python opencv实现人眼/人脸识别以及实时打码处理
2019/04/29 Python
Python 通过截图匹配原图中的位置(opencv)实例
2019/08/27 Python
Python venv虚拟环境配置过程解析
2020/07/08 Python
Matlab中plot基本用法的具体使用
2020/07/17 Python
Python使用正则表达式实现爬虫数据抽取
2020/08/17 Python
css3实现一款模仿iphone样式的注册表单
2013/03/20 HTML / CSS
菲律宾票务网站:StubHub菲律宾
2018/04/21 全球购物
印度排名第一的蛋糕、鲜花和礼品送货:Winni
2019/08/02 全球购物
信息管理专业学生自荐信格式
2013/09/22 职场文书
地理科学专业毕业生求职信
2013/10/15 职场文书
百日安全活动总结
2014/05/04 职场文书
初中优秀教师事迹材料
2014/08/18 职场文书
领导班子四风表现材料
2014/08/23 职场文书
银行奉献演讲稿
2014/09/16 职场文书
民用住房租房协议书
2014/10/29 职场文书
教师研修随笔感言
2015/11/18 职场文书