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 相关文章推荐
ExtJS 2.0实用简明教程 之Ext类库简介
Apr 29 Javascript
JavaScript 反科里化 this [译]
Sep 20 Javascript
web开发人员学习jQuery的6大理由及jQuery的优势介绍
Jan 03 Javascript
php 中序列化和json使用介绍
Jul 08 Javascript
基于jQuery Circlr插件实现产品图片360度旋转
Sep 20 Javascript
JavaScript性能优化总结之加载与执行
Aug 11 Javascript
canvas绘制七巧板
Feb 03 Javascript
深入解析Vue 组件命名那些事
Jul 18 Javascript
angular指令笔记ng-options的使用方法
Sep 18 Javascript
React学习之事件绑定的几种方法对比
Sep 24 Javascript
Vue实现点击导航栏当前标签后变色功能
Aug 19 Javascript
深入理解javascript中的this
Feb 08 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
MySQL 日期时间函数常用总结
2012/06/12 PHP
thinkphp5.1框架实现格式化mysql时间戳为日期的方式小结
2019/10/10 PHP
修改发贴的编辑功能
2007/03/07 Javascript
利用了jquery的ajax实现二级联互动菜单
2013/12/02 Javascript
jquery复选框checkbox实现删除前判断
2014/04/20 Javascript
js键盘事件的keyCode
2014/07/29 Javascript
Javascript中Array用法实例分析
2015/06/13 Javascript
使用Javascript写的2048小游戏
2015/11/25 Javascript
jQuery的ajax下载blob文件
2016/07/21 Javascript
JS实现选定指定HTML元素对象中指定文本内容功能示例
2017/02/13 Javascript
利用nodejs监控文件变化并使用sftp上传到服务器
2017/02/18 NodeJs
jquery实现左右滑动式轮播图
2017/03/02 Javascript
jQuery插件HighCharts实现2D柱状图、折线图的组合多轴图效果示例【附demo源码下载】
2017/03/09 Javascript
10 种最常见的 Javascript 错误(频率最高)
2018/02/08 Javascript
vue webpack实用技巧总结
2018/04/24 Javascript
vue.js计算属性computed用法实例分析
2018/07/06 Javascript
使用JS判断移动端手机横竖屏状态
2018/07/30 Javascript
JS基于ES6新特性async await进行异步处理操作示例
2019/02/02 Javascript
基于axios 的responseType类型的设置方法
2019/10/29 Javascript
深入分析在Python模块顶层运行的代码引起的一个Bug
2014/07/04 Python
python实现linux下使用xcopy的方法
2015/06/28 Python
Python中的函数式编程:不可变的数据结构
2018/10/08 Python
python使用pdfminer解析pdf文件的方法示例
2018/12/20 Python
python 实现创建文件夹和创建日志文件的方法
2019/07/07 Python
python 如何调用远程接口
2020/09/11 Python
python自动化测试三部曲之unittest框架的实现
2020/10/07 Python
《唯一的听众》教学反思
2014/02/20 职场文书
竞聘演讲稿
2014/04/24 职场文书
优质护理服务演讲稿
2014/05/07 职场文书
交通工程专业推荐信
2014/09/06 职场文书
学习保证书怎么写
2015/02/26 职场文书
医学生自荐信范文(2016精选篇)
2016/01/28 职场文书
中国现代文学之经典散文三篇
2019/09/18 职场文书
Java Lambda表达式常用的函数式接口
2022/04/07 Java/Android
Python实现仓库管理系统
2022/05/30 Python