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 相关文章推荐
避免回车键导致的页面无意义刷新的解决方法
Apr 12 Javascript
angularJS 入门基础
Feb 09 Javascript
angular ng-repeat数组中的数组实例
Feb 18 Javascript
JavaScript实现form表单的多文件上传
Mar 27 Javascript
Vue 通过自定义指令回顾v-内置指令(小结)
Sep 03 Javascript
浅谈微信小程序flex布局基础
Sep 10 Javascript
微信小程序学习笔记之文件上传、下载操作图文详解
Mar 29 Javascript
小程序实现自定义导航栏适配完美版
Apr 02 Javascript
Vue实现根据hash高亮选项卡
May 27 Javascript
vue拖拽组件 vuedraggable API options实现盒子之间相互拖拽排序
Jul 08 Javascript
解决Layui中templet中a的onclick参数传递的问题
Sep 20 Javascript
面试中canvas绘制图片模糊图片问题处理
Mar 13 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/05/15 PHP
PHP网页游戏学习之Xnova(ogame)源码解读(十)
2014/06/24 PHP
对比分析php中Cookie与Session的异同
2016/02/19 PHP
三个思路解决laravel上传文件报错:413 Request Entity Too Large问题
2017/11/13 PHP
php实现网页上一页下一页翻页过程详解
2019/06/28 PHP
PHP使用DOM对XML解析处理操作示例
2019/07/04 PHP
php实现微信小程序授权登录功能(实现流程)
2019/11/13 PHP
基于PHP实现解密或加密Cloudflar邮箱保护
2020/06/24 PHP
奉献给JavaScript初学者的编写开发的七个细节
2011/01/11 Javascript
js控制CSS样式属性语法对照表
2012/12/11 Javascript
javascript for-in有序遍历json数据并探讨各个浏览器差异
2015/11/30 Javascript
深入理解jquery跨域请求方法
2016/05/18 Javascript
AngularJS基础 ng-copy 指令实例代码
2016/08/01 Javascript
纯JS实现轮播图
2017/02/22 Javascript
详解angular中通过$location获取路径(参数)的写法
2017/03/21 Javascript
KOA+egg.js集成kafka消息队列的示例
2018/11/09 Javascript
谈谈为什么你的 JavaScript 代码如此冗长
2019/01/30 Javascript
Python远程桌面协议RDPY安装使用介绍
2015/04/15 Python
Python 绘图和可视化详细介绍
2017/02/11 Python
小米5s微信跳一跳小程序python源码
2018/01/08 Python
Python贪心算法实例小结
2018/04/22 Python
Python实现网站表单提交和模板
2019/01/15 Python
安装Pycharm2019以及配置anconda教程的方法步骤
2019/11/11 Python
python3实现raspberry pi(树莓派)4驱小车控制程序
2020/02/12 Python
django 外键创建注意事项说明
2020/05/20 Python
Python通过文本和图片生成词云图
2020/05/21 Python
墨尔本照明批发商店:Mica Lighting
2017/12/28 全球购物
.net面试题
2016/09/17 面试题
Linux面试题LINUX系统类
2015/11/25 面试题
简单叙述一下MYSQL的优化
2016/05/09 面试题
我与祖国共奋进演讲稿
2014/09/13 职场文书
2015年基层党建工作汇报材料
2015/06/25 职场文书
Django实现drf搜索过滤和排序过滤
2021/06/21 Python
MySQL非空约束(not null)案例讲解
2021/08/23 MySQL
Java使用Unsafe类的示例详解
2021/09/25 Java/Android
Win11如何设置右键单击显示所有选项?Win11右键单击显示所有选项设置教程
2022/04/08 数码科技