浅谈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 相关文章推荐
扩展String功能方法
Sep 22 Javascript
JavaScript中的事件处理
Jan 16 Javascript
escape、encodeURI 和 encodeURIComponent 的区别
Mar 02 Javascript
用Jquery实现多级下拉框无刷新的联动
Dec 22 Javascript
在多个页面使用同一个HTML片段的代码
Mar 04 Javascript
file模式访问网页时iframe高度自适应解决方案
Jan 16 Javascript
详解jQuery移动页面开发中的ui-grid网格布局使用
Dec 03 Javascript
javascript js 操作数组 增删改查的简单实现
Jun 20 Javascript
Javascript中的 “&amp;” 和 “|” 详解
Feb 02 Javascript
js 原型对象和原型链理解
Feb 09 Javascript
基于JavaScript实现贪吃蛇游戏
Mar 16 Javascript
Vertx基于EventBus发送接受自定义对象
Nov 16 Javascript
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
CentOS 安装 PHP5.5+Redis+XDebug+Nginx+MySQL全纪录
2015/03/25 PHP
一个加载js文件的小脚本
2007/06/28 Javascript
js 数组实现一个类似ruby的迭代器
2009/10/27 Javascript
date.parse在IE和FF中的区别
2010/07/29 Javascript
js+JQuery返回顶部功能如何实现
2012/12/03 Javascript
JavaScript针对网页节点的增删改查用法实例
2015/02/02 Javascript
js获取当前日期前七天的方法
2015/02/28 Javascript
jQuery+html5+css3实现圆角无刷新表单带输入验证功能代码
2015/08/21 Javascript
详解JavaScript UTC时间转换方法
2016/01/07 Javascript
原生 JS Ajax,GET和POST 请求实例代码
2016/06/08 Javascript
JavaScript必知必会(六) delete in instanceof
2016/06/08 Javascript
新闻上下滚动jquery 超简洁(必看篇)
2017/01/21 Javascript
Node.js发送HTTP客户端请求并显示响应结果的方法示例
2017/04/12 Javascript
webpack实现热加载自动刷新的方法
2017/07/30 Javascript
vue引入jq插件的实例讲解
2017/09/12 Javascript
React Native实现地址挑选器功能
2017/10/24 Javascript
微信小程使用swiper组件实现图片轮播切换显示功能【附源码下载】
2017/12/12 Javascript
vue中重定向redirect:‘/index‘,不显示问题、跳转出错的完美解决
2020/09/28 Javascript
原生JS实现音乐播放器
2021/01/26 Javascript
[02:52]2017DOTA2国际邀请赛中国区预选赛晋级之路
2017/07/03 DOTA
Python网络爬虫中的同步与异步示例详解
2018/02/03 Python
Python 脚本获取ES 存储容量的实例
2018/12/27 Python
10分钟用python搭建一个超好用的CMDB系统
2019/07/17 Python
CSS3 实现穿梭星空动画
2020/11/13 HTML / CSS
西班牙汉普顿小姐:购买帆布鞋和太阳镜
2016/10/23 全球购物
英国领先的在线药房:Pharmacy First
2017/09/10 全球购物
本科生详细的自我评价
2013/09/19 职场文书
演讲稿祖国在我心中
2014/05/04 职场文书
校庆标语集锦
2014/06/25 职场文书
2016中秋节晚会开场白
2015/11/26 职场文书
素质教育学习心得体会
2016/01/19 职场文书
学者《孟子》名人名言
2019/08/09 职场文书
写好Python代码的几条重要技巧
2021/05/21 Python
MySQL 发生同步延迟时Seconds_Behind_Master还为0的原因
2021/06/21 MySQL
CSS的calc函数用法小结
2022/06/25 HTML / CSS
Oracle删除归档日志及添加定时任务
2022/06/28 Oracle