浅析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 相关文章推荐
跨浏览器开发经验总结(三)   警惕“IE依赖综合症”
May 13 Javascript
让AJAX不依赖后端接口实现方案
Dec 03 Javascript
jQuery中outerHeight()方法用法实例
Jan 19 Javascript
JS实现的二叉树算法完整实例
Apr 06 Javascript
Bootstrap实现基于carousel.js框架的轮播图效果
May 02 Javascript
vue使用drag与drop实现拖拽的示例代码
Sep 07 Javascript
简单的Vue SSR的示例代码
Jan 12 Javascript
Vue二次封装axios为插件使用详解
May 21 Javascript
this在vue和小程序中的使用详解
Jan 28 Javascript
小程序接入腾讯位置服务的详细流程
Mar 03 Javascript
JavaScript 链表定义与使用方法示例
Apr 28 Javascript
Axios代理配置及封装响应拦截处理方式
Apr 07 Vue.js
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
php二分法在IP地址查询中的应用
2008/08/12 PHP
PHP基于php_imagick_st-Q8.dll实现JPG合成GIF图片的方法
2014/07/11 PHP
PHP中创建图像并绘制文字的例子
2014/11/19 PHP
php启用sphinx全文搜索的实现方法
2014/12/24 PHP
PHP实现获取FLV文件的时间
2015/02/10 PHP
PHP中header用法小结
2016/05/23 PHP
PHP通过微信跳转的Code参数获取用户的openid(关键代码)
2016/07/06 PHP
php大小写转换函数(strtolower、strtoupper)用法介绍
2017/11/17 PHP
阿里云Win2016安装Apache和PHP环境图文教程
2018/03/11 PHP
Prototype ObjectRange对象学习
2009/07/19 Javascript
浅谈JavaScript异常处理语句
2015/06/26 Javascript
AngularJS中过滤器的使用与自定义实例代码
2016/09/17 Javascript
通过BootStrap-select插件 js jQuery控制select属性变化
2017/01/03 Javascript
js省市区级联查询(插件版&amp;无插件版)
2017/03/21 Javascript
[01:02:03]2014 DOTA2华西杯精英邀请赛 5 24 NewBee VS VG
2014/05/26 DOTA
python 提取文件的小程序
2009/07/29 Python
在Python的Django框架下使用django-tagging的教程
2015/05/30 Python
tensorflow实现逻辑回归模型
2018/09/08 Python
OpenCV HSV颜色识别及HSV基本颜色分量范围
2019/03/22 Python
Python GUI学习之登录系统界面篇
2019/08/21 Python
Python yield生成器和return对比代码实例
2020/04/20 Python
Python+OpenCV图像处理——图像二值化的实现
2020/10/24 Python
使用python实现学生信息管理系统
2021/02/25 Python
CSS3 clip-path 用法介绍详解
2018/03/01 HTML / CSS
css3实现多个元素依次显示效果
2017/12/12 HTML / CSS
纽约市的奢华内衣目的地:Anya Lust
2019/08/02 全球购物
政法学院毕业生求职信
2014/02/28 职场文书
金融学专业大学生职业生涯规划
2014/03/07 职场文书
表彰会主持词
2014/03/26 职场文书
竞选卫生委员演讲稿
2014/04/28 职场文书
职工擅自离岗检讨书
2014/09/23 职场文书
新人入职感言
2015/07/31 职场文书
python爬取企查查企业信息之selenium自动模拟登录企查查
2021/04/08 Python
解决Pytorch中关于model.eval的问题
2021/05/22 Python
Python中的tkinter库简单案例详解
2022/01/22 Python
Python开发简易五子棋小游戏
2022/05/02 Python