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中json对象和string对象之间相互转化
Dec 26 Javascript
JavaScript动态提示输入框输入字数的方法
Jul 27 Javascript
常用原生JS兼容性写法汇总
Apr 27 Javascript
jQuery制作input提示内容(兼容IE8以上)
Jul 05 jQuery
Node.JS更改Windows注册表Regedit的方法小结
Aug 18 Javascript
js禁止表单重复提交
Aug 29 Javascript
解决layer弹层遮罩挡住窗体的问题
Aug 17 Javascript
JS数组求和的常用方法实例小结
Jan 07 Javascript
基于vue+axios+lrz.js微信端图片压缩上传方法
Jun 25 Javascript
ES6 Object属性新的写法实例小结
Jun 25 Javascript
基于纯JS实现多张图片的懒加载Lazy过程解析
Oct 14 Javascript
JS实现图片幻灯片效果代码实例
May 21 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数组实现无限分类,不使用数据库,不使用递归.
2006/12/09 PHP
php使用Imagick生成图片的方法
2015/07/31 PHP
通过Jquery遍历Json的两种数据结构的实现代码
2011/01/19 Javascript
js 函数调用模式小结
2011/12/26 Javascript
jQuery文本框(input textare)事件绑定方法教程
2013/04/24 Javascript
JQuery制作的放大效果的popup对话框(未添加任何jquery plugin)分享
2013/04/28 Javascript
浅谈javascript中的instanceof和typeof
2015/02/27 Javascript
JQuery中ajax方法访问web服务实例
2015/07/18 Javascript
jQuery实现仿百度帖吧头部固定导航效果
2015/08/07 Javascript
深入理解JavaScript函数参数(推荐)
2016/07/26 Javascript
浅谈移动端之js touch事件 手势滑动事件
2016/11/07 Javascript
Vuex2.0+Vue2.0构建备忘录应用实践
2016/11/30 Javascript
详解nodejs中exports和module.exports的区别
2017/02/17 NodeJs
Vue之Watcher源码解析(2)
2017/07/19 Javascript
浅谈express 中间件机制及实现原理
2017/08/31 Javascript
基于js中的原型(全面讲解)
2017/09/19 Javascript
小程序图片剪裁加旋转的示例代码
2018/07/10 Javascript
Vuex的初探与实战小结
2018/11/26 Javascript
TypeScript中的方法重载详解
2019/04/12 Javascript
webpack常用构建优化策略小结
2019/11/21 Javascript
[02:08]2014DOTA2国际邀请赛 430专访:力争取得小组前二
2014/07/11 DOTA
python 从远程服务器下载日志文件的程序
2013/02/10 Python
python实现读取excel写入mysql的小工具详解
2017/11/20 Python
python 随机生成10位数密码的实现代码
2019/06/27 Python
Python 硬币兑换问题
2019/07/29 Python
Python3.7安装keras和TensorFlow的教程图解
2020/06/18 Python
python实现按日期归档文件
2021/01/30 Python
澳大利亚婴儿礼品公司:The Baby Gift Company
2018/11/04 全球购物
李维斯牛仔裤英国官方网站:Levi’s英国
2019/10/10 全球购物
土建专业大学生自荐信范文
2014/04/09 职场文书
公司建议书怎么写
2014/05/15 职场文书
2015年度个人思想工作总结
2015/04/08 职场文书
烈士陵园观后感
2015/06/08 职场文书
2019个人工作计划书的格式及范文!
2019/07/04 职场文书
Django项目配置Memcached和Redis, 缓存选择哪个更有优势
2021/04/06 Python
蓝牙耳机怎么连接电脑win11? Win11蓝牙耳机连接电脑的技巧
2023/01/09 数码科技