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 相关文章推荐
jQuery+ajax实现鼠标单击修改内容的方法
Jun 27 Javascript
用svg制作富有动态的tooltip
Jul 17 Javascript
jquery Deferred 快速解决异步回调的问题
Apr 05 Javascript
微信小程序 Page()函数详解
Oct 17 Javascript
Web前端开发之水印、图片验证码
Nov 27 Javascript
理解javascript中的闭包
Jan 11 Javascript
vue.js中过滤器的使用教程
Jun 08 Javascript
JavaScript中的return布尔值的用法和原理解析
Aug 14 Javascript
vue项目打包部署_nginx代理访问方法详解
Sep 20 Javascript
vue-cli3搭建项目的详细步骤
Dec 05 Javascript
vue中提示$index is not defined错误的解决方式
Sep 02 Javascript
Vue CLI中模式与环境变量的深入详解
May 30 Vue.js
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
使用Limit参数优化MySQL查询的方法
2008/11/12 PHP
header中Content-Disposition的作用与使用方法
2012/06/13 PHP
php实现保存submit内容之后禁止刷新
2014/03/19 PHP
PHP实现递归复制整个文件夹的类实例
2015/08/03 PHP
ThinkPHP数据操作方法总结
2015/09/28 PHP
php进程间通讯实例分析
2016/07/11 PHP
常用PHP数组排序函数归纳
2016/08/08 PHP
不常用但很实用的PHP预定义变量分析
2019/06/25 PHP
thinkphp框架实现路由重定义简化url访问地址的方法分析
2020/04/04 PHP
List Information About the Binary Files Used by an Application
2007/06/11 Javascript
jQuery 处理网页内容的实现代码
2010/02/15 Javascript
事件绑定之小测试  onclick && addEventListener
2011/07/31 Javascript
NodeJS与HTML5相结合实现拖拽多个文件上传到服务器的实现方法
2016/07/26 NodeJs
JavaScript每天必学之事件
2016/09/18 Javascript
JS实现图片上传预览功能
2016/11/21 Javascript
原生js实现鼠标跟随效果
2017/02/28 Javascript
Angular4 组件通讯方法大全(推荐)
2018/07/12 Javascript
Vue编写可显示周和月模式的日历 Vue自定义日历内容的显示
2019/06/26 Javascript
详解vue中使用axios对同一个接口连续请求导致返回数据混乱的问题
2019/11/06 Javascript
微信小程序实现倒计时功能
2020/11/19 Javascript
element-plus一个vue3.xUI框架(element-ui的3.x 版初体验)
2020/12/02 Vue.js
Python OpenCV实现图片上输出中文
2018/01/22 Python
Go/Python/Erlang编程语言对比分析及示例代码
2018/04/23 Python
十分钟利用Python制作属于你自己的个性logo
2018/05/07 Python
详解Python的数据库操作(pymysql)
2019/04/04 Python
pytorch 在sequential中使用view来reshape的例子
2019/08/20 Python
Python itertools.product方法代码实例
2020/03/27 Python
Python实现动态循环输出文字功能
2020/05/07 Python
Django全局启用登陆验证login_required的方法
2020/06/02 Python
Python3爬虫里关于识别微博宫格验证码的知识点详解
2020/07/30 Python
英文求职信结束语大全
2013/10/26 职场文书
初中英语教学反思
2014/01/25 职场文书
董事长秘书工作职责
2014/06/10 职场文书
音乐教师个人总结
2015/02/06 职场文书
修辞手法有哪些?
2019/08/29 职场文书
Vscode中SSH插件如何远程连接Linux
2022/05/02 Servers