vue源码学习之Object.defineProperty对象属性监听


Posted in Javascript onMay 30, 2018

本文介绍了vue源码学习之Object.defineProperty对象属性监听,分享给大家,具体如下:

参考版本 vue源码版本:0.11

相关

vue实现双向数据绑定的关键是 Object.defineProperty ,让我们先来看下这个函数。

在MDN上查看有关Object.defineProperty 的解释。

我们先从最简单的开始:

let a = {'b': 1};
Object.defineProperty(a, 'b', {
  enumerable: false,
  configurable: false,
  get: function(){
    console.log('b' + '被访问');
  },
  set: function(newVal){
    console.log('b' + '被修改,新' + 'b' + '=' + newVal);
  }
});

a.b = 2;  // b被修改,新b=2
a.b;    // b被访问

这样,我们就能监听对象了!但问题并不仅仅这么简单。。。

我们可能会有对象中属性的值还是对象这种嵌套情况,可以通过递归解决!

在vue源代码文件 srcobserveobserver.js 中

// 观察者构造函数
function Observer(data){
  this.data = data;
  this.walk(data);
}

let p = Observer.prototype;
p.walk = function(obj){
  let val;
  for(let key in obj){
    // 通过 hasOwnProperty 过滤掉一个对象本身拥有的属性 
    if(obj.hasOwnProperty(key)){
      val = obj[key];
      // 递归调用 循环所有对象出来
      if(typeof val === 'object'){
        new Observer(val);
      }
      this.convert(key, val);
    }
  }
};

p.convert = function(key, val){
  Object.defineProperty(this.data, key, {
    enumerable: false,
    configurable: false,
    get: function(){
      console.log(key + '被访问');
    },
    set: function(newVal){
      console.log(key + '被修改,新' + key + '=' + newVal);
      if(newVal === val) return ;
      val = newVal;
    }
  })
};

let data = {
  user: {
    name: 'zhangsan',
    age: 14
  },
  address: {
    city: 'beijing'
  }
}

let app = new Observer(data);
data.user.name;  // user被访问

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
33种Javascript 表格排序控件收集
Dec 03 Javascript
cocos2dx骨骼动画Armature源码剖析(三)
Sep 08 Javascript
BootStrap 智能表单实战系列(二)BootStrap支持的类型简介
Jun 13 Javascript
详解webpack 配合babel 将es6转成es5 超简单实例
May 02 Javascript
js求数组中全部数字可拼接出的最大整数示例代码
Aug 25 Javascript
vue axios同步请求解决方案
Sep 29 Javascript
纯javascript实现选择框的全选与反选功能
Apr 08 Javascript
使用Vue实现移动端左滑删除效果附源码
May 16 Javascript
vue实现pdf文档在线预览功能
Nov 26 Javascript
vue动态渲染svg、添加点击事件的实现
Mar 13 Javascript
JavaScript设计模式--桥梁模式引入操作实例分析
May 23 Javascript
解决antd 表单设置默认值initialValue后验证失效的问题
Nov 02 Javascript
Angular搜索场景中使用rxjs的操作符处理思路
May 30 #Javascript
微信小程序实现跑马灯效果完整代码(附效果图)
May 30 #Javascript
vue通过点击事件读取音频文件的方法
May 30 #Javascript
vue 表单输入格式化中文输入法异常问题
May 30 #Javascript
详解如何使用babel进行es6文件的编译
May 29 #Javascript
基于打包工具Webpack进行项目开发实例
May 29 #Javascript
JavaScript反射与依赖注入实例详解
May 29 #Javascript
You might like
PHP中的加密功能
2006/10/09 PHP
php中foreach结合curl实现多线程的方法分析
2016/09/22 PHP
php使用fputcsv实现大数据的导出操作详解
2020/02/27 PHP
ExtJS Grid使用SimpleStore、多选框的方法
2009/11/20 Javascript
javascript使用百度地图api和html5特性获取浏览器位置
2014/01/10 Javascript
JS获得图片alt信息的方法
2015/04/01 Javascript
CSS javascript 结合实现悬浮固定菜单效果
2015/08/23 Javascript
jquery实现倒计时功能
2015/12/28 Javascript
关于session和cookie的简单理解
2016/06/08 Javascript
ng-options和ng-checked在表单中的高级运用(推荐)
2017/01/21 Javascript
ionic实现底部分享功能
2017/05/11 Javascript
node使用Koa2搭建web项目的方法
2017/10/17 Javascript
详解vue 不同环境配置不同的打包命令
2019/04/07 Javascript
20多个小事例带你重温ES10新特性(小结)
2019/09/29 Javascript
mpvue实现左侧导航与右侧内容的联动
2019/10/21 Javascript
[00:36]DOTA2勇士令状莱恩声望物品——冥晶之厄展示
2018/05/25 DOTA
PyQt5每天必学之像素图控件QPixmap
2018/04/19 Python
使用python将大量数据导出到Excel中的小技巧分享
2018/06/14 Python
Python笔记之facade模式
2019/11/20 Python
Python中Subprocess的不同函数解析
2019/12/10 Python
Python通过TensorFLow进行线性模型训练原理与实现方法详解
2020/01/15 Python
Selenium启动Chrome时配置选项详解
2020/03/18 Python
Python环境下安装PyGame和PyOpenGL的方法
2020/03/25 Python
在Ubuntu 20.04中安装Pycharm 2020.1的图文教程
2020/04/30 Python
python二维图制作的实例代码
2020/12/03 Python
微信小程序实现可实时改变转速的css3旋转动画实例代码
2018/09/11 HTML / CSS
html如何对span设置宽度
2019/10/30 HTML / CSS
迷你分体式空调:SoGoodToBuy
2018/08/07 全球购物
财务会计毕业生自荐信
2013/11/02 职场文书
企业车辆管理制度
2014/01/24 职场文书
社区居务公开实施方案
2014/03/27 职场文书
财务负责人任命书
2014/06/06 职场文书
2014年大学生工作总结
2014/11/20 职场文书
导游词之丽江普济寺
2019/10/22 职场文书
导游词之镜泊湖
2019/12/09 职场文书
JavaScript设计模式之原型模式详情
2022/06/21 Javascript