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 相关文章推荐
服务器安全设置的几个注册表设置
Jul 28 Javascript
animate动画示例(泪奔的小孩)及stop和delay的使用
May 06 Javascript
js原生appendChild的bug解决心得分享
Jul 01 Javascript
javascript html5移动端轻松实现文件上传
Mar 27 Javascript
浅析jQuery 3.0中的Data
Jun 14 Javascript
javascript创建含数字字母的随机字符串方法总结
Aug 01 Javascript
web前端开发upload上传头像js示例代码
Oct 22 Javascript
微信开发 使用picker封装省市区三级联动模板
Oct 28 Javascript
JS闭包可被利用的常见场景小结
Apr 09 Javascript
jquery引入外部CDN 加载失败则引入本地jq库
May 23 jQuery
vue使用Google地图的实现示例代码
Dec 19 Javascript
js实现简单进度条效果
Mar 25 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函数之error_reporting(E_ALL ^ E_NOTICE)详细说明
2011/07/01 PHP
php 使用expat方式解析xml文件操作示例
2019/11/26 PHP
Laravel5.1 框架Request请求操作常见用法实例分析
2020/01/04 PHP
javascript 尚未实现错误解决办法
2008/11/27 Javascript
javascript变量作用域使用中常见错误总结
2013/03/26 Javascript
JS关闭窗口或JS关闭页面的几种代码分享
2013/10/25 Javascript
Jquery 动态循环输出表格具体方法
2013/11/23 Javascript
JavaScript中使用document.write向页面输出内容实例
2014/10/16 Javascript
JavaScript+html5 canvas制作的百花齐放效果完整实例
2016/01/26 Javascript
JavaScript实现实时更新系统时间的实例代码
2017/04/04 Javascript
Vue中之nextTick函数源码分析详解
2017/10/17 Javascript
js正则相关知识点专题
2018/05/10 Javascript
vue 路由嵌套高亮问题的解决方法
2018/05/17 Javascript
详解如何在微信小程序中愉快地使用sass
2018/07/30 Javascript
Javascript实现秒表计时游戏
2020/05/27 Javascript
在Python的Django框架中创建和使用模版
2015/07/15 Python
详解Python字符串对象的实现
2015/12/24 Python
python实现识别相似图片小结
2016/02/22 Python
python利用不到一百行代码实现一个小siri
2017/03/02 Python
浅谈python和C语言混编的几种方式(推荐)
2017/09/27 Python
python使用生成器实现可迭代对象
2018/03/20 Python
在pycharm中python切换解释器失败的解决方法
2018/10/29 Python
python,Django实现的淘宝客登录功能示例
2019/06/12 Python
python加密解密库cryptography使用openSSL生成的密匙加密解密
2020/02/11 Python
pytorch  网络参数 weight bias 初始化详解
2020/06/24 Python
win10安装python3.6的常见问题
2020/07/01 Python
美国蔬菜和植物种子公司:Burpee
2017/02/01 全球购物
回馈慈善的设计师太阳镜:DIFF eyewear
2019/10/17 全球购物
2014年父亲节活动方案
2014/03/06 职场文书
关于工作经历的证明书
2014/10/11 职场文书
优秀团队申报材料
2014/12/26 职场文书
党员检讨书范文
2014/12/27 职场文书
中学生综合素质自我评价
2015/03/06 职场文书
用Python写一个简易版弹球游戏
2021/04/13 Python
MySQL 分页查询的优化技巧
2021/05/12 MySQL
如何使用Python实现一个简易的ORM模型
2021/05/12 Python