浅析vue数据绑定


Posted in Javascript onJanuary 17, 2017

前言:最近团队需要做一个分享,脚进脑子,不知如何分享。最后想着之前一直想研究一下 vue 源码,今天刚好 “借此机会” 研究一下。

网上研究vue数据绑定的文章已经非常多了,但是自己写一遍,敲一遍demo和看别人的文章是完全不同的,so……搬运工来了

目前数据绑定主要有以下三种实现方式:

1.   脏值检查(angular.js)    轮询检测数据变化

DOM事件,譬如用户输入文本,点击按钮等。( ng-click )

  • XHR响应事件 ( $http )
  • 浏览器Location变更事件 ( $location )
  • Timer事件( $timeout , $interval )
  • 执行 $digest() 或 $apply()

2、Object.defineProperty劫持对象的get、set,从而实现对数据的监控。 (vue)

3、发布/订阅者模式实现数据与视图的自动同步

Object.defineProperty的优点

  • “脏值检测”——数据发生变更后,对于所有的数据和视图的绑定关系进行一次检测,识别是否有数据发生了改变,有变化进行处理,可能进一步引发其他数据的改变,所以这个过程可能会循环几次,一直到不再有数据变化发生后,将变更的数据发送到视图,更新页面展现
  • Object.defineProperty() 监控对数据的操作,可以自动触发数据同步。并且,由于是在不同的数据上触发同步,可以精确的将变更发送给绑定的视图,而不是对所有的数据都执行一次检测。

Object.defineProperty的用法

var a = {};

Object.defineProperty(a, "b", {
 
 set: function (newValue) {
 
 console.log("我被赋值了!" + newValue);
 
 },
 
 get: function () {
 
 console.log("我被取值了!");
 
 return 2 
 }
})

a.b = 3; //我被赋值了!

console.log(a.b); //我被取值了! //打印 2

由上面的例子看出,Object.defineProperty  传人3个参数

第一个: a对象

第二个: a对象里面的b属性

第三个: 属性比较多,列举有用的 value,set,get,configurable

数据绑定原理:

1、实现一个数据监听器Observer,对数据对象的所有属性进行监听,如有变动则拿到最新值并通知 dep数组

2、实现一个指令解析器Compile,对每个元素节点的指令进行扫描和解析,根据指令模板替换数据

3、实现一个dep数组 ,能够订阅并收到每个属性变动的通知,执行指令绑定的相应回调函数,更新视图

1. 实现observer

var data = {name: 'beidan'};

observe(data);

data.name = 'test'; // 监听到值变化了 beidan 变成 test

function observe(data) {
 
 if (!data || typeof data !== 'object') {
 
 return;
 
 }
 
 // 取出所有属性遍历
 
 Object.keys(data).forEach(function(key) {
 
  defineReactive(data, key, data[key]);

 });
}
function defineReactive(data, key, val) {


 Object.defineProperty(data, key, {

 enumerable: true, // 可枚举
 
  configurable: false, // 不能再define
  get: function() {
  
   return val;
 
  },
 
  set: function(newVal) {
  
   console.log('监听到值变化了 ', val, ' 变成 ', newVal);

   val = newVal;
 
  }
 
 });
}

2. 维护一个数组

function Dep() {
 
 this.subs = [];
}

Dep.prototype = {
 
 addSub: function (sub) {
 
 this.subs.push(sub);
 
 },
 
 notify: function (val) {
 
  this.subs.forEach(function (sub) {
  
  sub.update(val)
 
 });
 
}
};
function defineReactive(data, key, val) {
 Object.defineProperty(data, key, {
 ……
 set: function(newVal) {
  if (val === newVal) return;
  console.log('监听到值变化了 ', val, ' 变成 ', newVal);
  val = newVal;
  dep.notify(val); // 通知所有订阅者 
 } 
 });
}

3. compile

bindText: function () {
 
 var textDOMs = this.el.querySelectorAll('[v-text]'),
bindText,_context = this;

 
 for (var i = 0; i < textDOMs.length; i++) {
  
 bindText = textDOMs[i].getAttribute('v-text');
 textDOMs[i].innerHTML = this.data[bindText];

 var val = textDOMs[i]

 
 var up = function (text) {
  
  val.innerText = text
 
 }

 _context.dep.addSub({
  
  value: textDOMs[i],
  
  update: up
 
 });
 
 }
},

最后,附上源码 github   https://github.com/beidan/vue_bind

参考链接:

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持三水点靠木!

Javascript 相关文章推荐
js实现的全国省市二级联动下拉选择菜单完整实例
Aug 17 Javascript
js运动应用实例解析
Dec 28 Javascript
简单实现jQuery手风琴效果
Aug 18 jQuery
JavaSctit 利用FileReader和滤镜上传图片预览功能
Sep 05 Javascript
bootstrap-table组合表头的实现方法
Sep 07 Javascript
vue.js的computed,filter,get,set的用法及区别详解
Mar 08 Javascript
Vue如何实现响应式系统
Jul 11 Javascript
vue router 配置路由的方法
Jul 26 Javascript
说说如何使用Vuex进行状态管理(小结)
Apr 14 Javascript
解决layUI的页面显示不全的问题
Sep 20 Javascript
在vue-cli创建的项目中使用sass操作
Aug 10 Javascript
如何利用React实现图片识别App
Feb 18 Javascript
JavaScript使用正则表达式获取全部分组内容的方法示例
Jan 17 #Javascript
JavaScript使用delete删除数组元素用法示例【数组长度不变】
Jan 17 #Javascript
微信小程序 缓存(本地缓存、异步缓存、同步缓存)详解
Jan 17 #Javascript
详谈JavaScript的闭包及应用
Jan 17 #Javascript
用原生js做单页应用
Jan 17 #Javascript
js cookie实现记住密码功能
Jan 17 #Javascript
angularjs ocLazyLoad分步加载js文件实例
Jan 17 #Javascript
You might like
destoon复制新模块的方法
2014/06/21 PHP
完美利用Yii2微信后台开发的系列总结
2016/07/18 PHP
PHPStorm 2020.1 调试 Nodejs的多种方法详解
2020/09/17 NodeJs
JavaScript和JQuery实用代码片段(一)
2010/04/07 Javascript
Javascript表达式中连续的 &amp;&amp; 和 || 之赋值区别
2010/10/17 Javascript
juqery 学习之五 文档处理 插入
2011/02/11 Javascript
js简单实现根据身份证号码识别性别年龄生日
2013/11/29 Javascript
js 动态为textbox添加下拉框数据源的方法
2014/04/24 Javascript
JavaScript中的值是按值传递还是按引用传递问题探讨
2015/01/30 Javascript
理解 JavaScript Scoping &amp; Hoisting(二)
2015/11/18 Javascript
JavaScript实现跑马灯抽奖活动实例代码解析与优化(二)
2016/02/16 Javascript
js中用cssText设置css样式的简单方法
2016/09/19 Javascript
EasyUI修改DateBox和DateTimeBox的默认日期格式示例
2017/01/18 Javascript
javascript 显示全局变量与隐式全局变量的区别
2017/02/09 Javascript
微信小程序图片选择、上传到服务器、预览(PHP)实现实例
2017/05/11 Javascript
jQuery实现数字华容道小游戏(实例代码)
2020/01/16 jQuery
[06:42]DOTA2每周TOP10 精彩击杀集锦vol.1
2014/06/25 DOTA
[38:44]DOTA2上海特级锦标赛A组小组赛#2 Secret VS CDEC第二局
2016/02/25 DOTA
Python中的进程分支fork和exec详解
2015/04/11 Python
python对html代码进行escape编码的方法
2015/05/04 Python
简单介绍使用Python解析并修改XML文档的方法
2015/10/15 Python
python3通过selenium爬虫获取到dj商品的实例代码
2019/04/25 Python
Python中的几种矩阵乘法(小结)
2019/07/10 Python
Python目录和文件处理总结详解
2019/09/02 Python
html5 Canvas画图教程(6)—canvas里画曲线之arcTo方法
2013/01/09 HTML / CSS
详解淘宝H5 sign加密算法
2020/08/25 HTML / CSS
乌克兰电子产品和家用电器购物网站:TOUCH
2019/08/09 全球购物
金融专业个人求职信
2013/09/22 职场文书
如何写自我评价?自我评价写什么好?
2014/03/14 职场文书
十佳好少年事迹材料
2014/08/21 职场文书
运动会演讲稿50字
2014/08/25 职场文书
民事赔偿协议书
2014/11/02 职场文书
2014年学校总务处工作总结
2014/12/08 职场文书
母亲节寄语大全
2015/02/27 职场文书
小学一年级语文教学反思
2016/03/03 职场文书
Spring Boot项目如何优雅实现Excel导入与导出功能
2022/06/10 Java/Android