浅析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 相关文章推荐
javascript arguments 传递给函数的隐含参数
Aug 21 Javascript
javascript 三种编解码方式
Feb 01 Javascript
js jquery数组介绍
Jul 15 Javascript
jquery $(&quot;#variable&quot;) 循环改变variable的值示例
Feb 23 Javascript
浅谈jQuery异步对象(XMLHttpRequest)
Nov 17 Javascript
使用jquery操作session方法分享
Jan 22 Javascript
详细谈谈javascript的对象
Jul 31 Javascript
ES6新特性之Symbol类型用法分析
Mar 31 Javascript
Vue不能检测到Object/Array更新的情况的解决
Jun 26 Javascript
express框架下使用session的方法
Jul 31 Javascript
JS实现字体背景跑马灯
Jan 06 Javascript
详解Node.JS模块 process
Aug 31 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
关于php正则匹配汉字的方法介绍
2013/04/25 PHP
PHP保留两位小数并且四舍五入及不四舍五入的方法
2013/09/22 PHP
PHP使用pear自带的mail类库发邮件的方法
2015/07/08 PHP
php.ini中date.timezone设置详解
2016/11/20 PHP
静态html文件执行php语句的方法(推荐)
2016/11/21 PHP
利用PHP获取汉字首字母并且分组排序详解
2017/10/22 PHP
JS字符串函数扩展代码
2011/09/13 Javascript
JS利用cookie记忆当前位置的防刷新导航效果
2015/10/15 Javascript
javascript面向对象程序设计高级特性经典教程(值得收藏)
2016/05/19 Javascript
Javascript中常见的逻辑题和解决方法
2016/09/17 Javascript
ThinkJS中如何使用MongoDB的CURD操作
2016/12/13 Javascript
Vue原理剖析 实现双向绑定MVVM
2017/05/03 Javascript
动态统计当前输入内容的字节、字符数的实例详解
2017/10/27 Javascript
redux-saga 初识和使用
2018/03/10 Javascript
vue兄弟组件传递数据的实例
2018/09/06 Javascript
jQuery实现高度灵活的表单验证功能示例【无UI】
2020/04/30 jQuery
vue 使用微信jssdk,调用微信相册上传图片功能
2020/11/13 Javascript
python的keyword模块用法实例分析
2015/06/30 Python
详解使用Python处理文件目录的相关方法
2015/10/16 Python
Tornado协程在python2.7如何返回值(实现方法)
2017/06/22 Python
使用python的pandas库读取csv文件保存至mysql数据库
2018/08/20 Python
Python用5行代码写一个自定义简单二维码
2018/10/21 Python
Python3常用内置方法代码实例
2019/11/18 Python
Python爬虫爬取煎蛋网图片代码实例
2019/12/16 Python
详解Python 中的容器 collections
2020/08/17 Python
java字符串格式化输出实例讲解
2021/01/06 Python
深入理解Python变量的数据类型和存储
2021/02/01 Python
Maison Lab荷兰:名牌Outlet购物
2018/08/10 全球购物
Java语言程序设计测试题选择题部分
2014/04/03 面试题
优秀志愿者事迹材料
2014/02/03 职场文书
产品生产计划书
2014/05/07 职场文书
2014年青年志愿者工作总结
2014/12/09 职场文书
2015年护士工作总结范文
2015/03/31 职场文书
2015年助理政工师工作总结
2015/05/26 职场文书
高三生物教学反思
2016/02/22 职场文书
Typescript类型系统FLOW静态检查基本规范
2022/05/25 Javascript