浅谈vue实现数据监听的函数 Object.defineProperty


Posted in Javascript onJune 08, 2017

在 ES5中新增了不少新的API, 例如  新增了 Object.xxx相关的方法,其中有一个定义属性相关的 Object.defineProperty 这个方法(还有Object.defineProperties)这个方法是 vue框架实现数据监听的核心方法,它的定义如下:

Object.defineProperty([Object] obj, [String] propname, [Object] desp )

  1. @param  obj  要配置属性的某个对象
  2. @param propname 要配置的属性名,是一个字符串
  3. @param desp 对属性的描述,是一个对象,

desp 中可以配置的项目 

<1> writable:  true/false 是否可写

<2> configurable : true/false 是否可以配置,例如删除该属性

<3> enumerable: true/false 指的是是否可以使用 for in循环遍历属性

<4> value:  值  ,属性的值

我们在写vue项目的时候会在 data属性中添加我们自己的属性,这个属性在vue中是响应式的,也就是它可以监听到数据的变化,做出相应的改变(例如DOM操作)

我们自己利用 defineProperty给属性生成setter和getter(也就是其他编程语言里的存取器),就可以达到监听数据变化的目的

下面我们来自己实现一个数据监听的小 demo

有如下的数据

let vue = {
   data: {
    title: 'life style',
    content: 'bike walk sleep...'
   }
  };

已经提前声明的 data属性及其内部的属性,我们的目标是监听 data中,title和content的变化

如何做到呢? 属性的个数是不确定的,所以我们可以使用 for in循环遍历data对象的所有的属性

//如何监听用户自定义的 data中属性的改变?
  let data = vue.data;
  for (let prop in data) {
   data['__' + prop] = data[prop]; //存储私有属性
   Object.defineProperty(data, prop, {
    enumerable : true,
    set: function (newVal) {
     console.log('你正在修改'+prop + ' !...操作DOM...');
     // 数据校验
     this['__' + prop] = newVal;
    },
    get: function () {
     console.log('getter 获取值 ...');
     return this['__' + prop];
    }
   });
  }

遍历data属性的时候调用 defineProperty来给data对象的属性添加set和get方法,

我们给data添加一个新的属性   __xxx来保存我们之前的值,以便在 get方法中获取原来的值

set方法 用于监听这个属性被重新赋值,

get方法用于获取你想要的格式的值

此处需要注意的是 不要在 set和get中 使用this赋值或者取值,这样会导致循环调用,出现问题!!!

另外 我们不要使用 var,而要使用 let ,因为var不是块作用域, 会导致你最后访问到的prop总是最后一个

定义好之后,我们可以修改 data中title和content属性了,

当我们给 title赋值的时候回自动调用 set, 获取值得时候自动调用get

测试代码

// 赋值操作会调用这个属性的set方法, 类似于 set('aaa')
  data.title = 'aaa';
  // 获取值操作会调用这个属性的get方法
  console.log(data.title);
  data.content = 123;
  // 此种动态属性方式也会触发 set / get
  data['title'] = 123;
  console.log(data['title']);

结果(建议在最新版的chrome中操作):

浅谈vue实现数据监听的函数 Object.defineProperty

对刚刚的遍历方法还存在一些问题和说明:

1.data属性的某个属性可能还是对象,也就是存在多层级对象监听的问题

此时可以使用递归函数遍历data的属性,进行相同操作

2. 通过  data.title = 1是实际上是调用了 set方法, 这个类似于 OC中的点语法

3. 要同时定义多个属性,可以使用

Object.defineProperties([Object] obj, [Object] props);

需要注意的是, 本文只是介绍 defineProperty的基本使用,并非代表vue的代码实现

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

Javascript 相关文章推荐
JavaScript Sort 表格排序
Oct 31 Javascript
javascript中关于执行环境的杂谈
Aug 14 Javascript
onmouseover和onmouseout的一些问题思考
Aug 14 Javascript
js判断上传文件的类型和大小示例代码
Oct 18 Javascript
node.js应用后台守护进程管理器Forever安装和使用实例
Jun 01 Javascript
jQuery中常用的遍历函数用法实例总结
Sep 01 Javascript
jQuery ready()和onload的加载耗时分析
Sep 08 Javascript
easy ui datagrid 从编辑框中获取值的方法
Feb 22 Javascript
Angular2.0实现modal对话框的方法示例
Feb 18 Javascript
Node.js assert断言原理与用法分析
Jan 04 Javascript
Vue中JS动画与Velocity.js的结合使用
Feb 13 Javascript
jQuery实时统计输入框字数及限制
Jun 24 jQuery
jQuery Validate表单验证插件实现代码
Jun 08 #jQuery
浅谈 Vue v-model指令的实现原理
Jun 08 #Javascript
Vue如何实现组件的源码解析
Jun 08 #Javascript
jquery Ajax实现Select动态添加数据
Jun 08 #jQuery
js canvas实现放大镜查看图片功能
Jun 08 #Javascript
vue实现一个移动端屏蔽滑动的遮罩层实例
Jun 08 #Javascript
微信小程序开发之map地图实现教程
Jun 08 #Javascript
You might like
基于数据库的在线人数,日访问量等统计
2006/10/09 PHP
php微信支付之APP支付方法
2015/03/04 PHP
PHP各种异常和错误的拦截方法及发生致命错误时进行报警
2016/01/19 PHP
php flush无效,IIS7下php实时输出的方法
2016/08/25 PHP
php.ini中date.timezone设置详解
2016/11/20 PHP
php和redis实现秒杀活动的流程
2019/07/17 PHP
jQuery函数的等价原生函数代码示例
2013/05/27 Javascript
利用javascript数组长度循环数组内所有元素
2013/12/27 Javascript
JS实现屏蔽shift,Ctrl,alt等功能键的方法
2015/06/01 Javascript
javascript类型系统 Window对象学习笔记
2016/01/07 Javascript
Angular1.x自定义指令实例详解
2017/03/01 Javascript
微信小程序注册60s倒计时功能 使用JS实现注册60s倒计时功能
2017/08/16 Javascript
vue-router实现组件间的跳转(参数传递)
2017/11/07 Javascript
微信小程序利用canvas 绘制幸运大转盘功能
2018/07/06 Javascript
详解如何在vue-cli中使用vuex
2018/08/07 Javascript
详解element-ui中form验证杂记
2019/03/04 Javascript
js+cavans实现图片滑块验证
2020/09/29 Javascript
vue实现点击出现操作弹出框的示例
2020/11/05 Javascript
python paramiko实现ssh远程访问的方法
2013/12/03 Python
Python排序算法实例代码
2017/08/10 Python
对numpy中轴与维度的理解
2018/04/18 Python
DES加密解密算法之python实现版(图文并茂)
2018/12/06 Python
django 自定义过滤器(filter)处理较为复杂的变量方法
2019/08/12 Python
python从内存地址上加载python对象过程详解
2020/01/08 Python
基于opencv实现简单画板功能
2020/08/02 Python
纯CSS3代码实现switch滑动开关按钮效果
2016/08/30 HTML / CSS
香港草莓网土耳其网站:Strawberrynet TR
2017/03/02 全球购物
婴儿鞋,独特的婴儿服装和配件:Zutano
2018/11/03 全球购物
标准导师推荐信(医学类)
2013/10/28 职场文书
文秘专业应届生求职信范文
2013/11/14 职场文书
葡萄牙语专业个人求职信
2013/12/10 职场文书
二年级评语大全
2014/04/23 职场文书
大学生军训自我鉴定范文
2014/09/18 职场文书
申报优秀教师材料
2014/12/16 职场文书
2014年变电站工作总结
2014/12/19 职场文书
2015年学雷锋活动总结
2015/02/06 职场文书