浅谈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 相关文章推荐
js实现在文本框光标处添加字符的方法介绍
Nov 24 Javascript
Node.js中使用事件发射器模式实现事件绑定详解
Aug 15 Javascript
一个检测表单数据的JavaScript实例
Oct 31 Javascript
用js读、写、删除Cookie代码续篇
Dec 03 Javascript
jQuery判断数组是否包含了指定的元素
Mar 10 Javascript
JS获取当前脚本文件的绝对路径
Mar 02 Javascript
COM组件中调用JavaScript函数详解及实例
Feb 23 Javascript
Javascript中click与blur事件的顺序详析
Apr 25 Javascript
jQuery实现html table行Tr的复制、删除、计算功能
Jul 10 jQuery
使用Node.js搭建静态资源服务详细教程
Aug 02 Javascript
详解wepy开发小程序踩过的坑(小结)
May 22 Javascript
vue瀑布流组件实现上拉加载更多
Mar 10 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
小谈php正则提取图片地址
2014/03/27 PHP
thinkphp中的url跳转用法分析
2016/07/12 PHP
PHP实现通过文本文件统计页面访问量功能示例
2019/02/13 PHP
thinkphp5.1框架容器与依赖注入实例分析
2019/07/23 PHP
phpStudy vscode 搭建debug调试的教程详解
2020/07/28 PHP
jquery checkbox,radio是否选中的判断代码
2010/03/20 Javascript
js解析与序列化json数据(三)json的解析探讨
2013/02/01 Javascript
原生js的弹出层且其内的窗口居中
2014/05/14 Javascript
JavaScript转换与解析JSON方法实例详解
2015/11/24 Javascript
js判断图片加载完成后获取图片实际宽高的方法
2016/02/25 Javascript
js简单实现图片延迟加载的方法
2016/07/19 Javascript
Angular 页面跳转时传参问题
2016/08/01 Javascript
JavaScript触发onScroll事件的函数节流详解
2016/12/14 Javascript
AngularJS学习笔记之表单验证功能实例详解
2017/07/06 Javascript
vue.js如何更改默认端口号8080为指定端口的方法
2017/07/14 Javascript
node中koa中间件机制详解
2017/08/22 Javascript
Layui数据表格之获取表格中所有的数据方法
2018/08/20 Javascript
vue中使用element ui的弹窗与echarts之间的问题详解
2019/10/25 Javascript
Vue快速实现通用表单验证的示例代码
2020/01/09 Javascript
JavaScript, select标签元素左右移动功能实现
2020/05/14 Javascript
Vue实现简单的拖拽效果
2020/08/25 Javascript
在Django中URL正则表达式匹配的方法
2018/12/20 Python
详解mac python+selenium+Chrome 简单案例
2019/11/08 Python
pytorch中torch.max和Tensor.view函数用法详解
2020/01/03 Python
浅析Python 多行匹配模式
2020/07/24 Python
Python文件操作及内置函数flush原理解析
2020/10/13 Python
Python基于execjs运行js过程解析
2020/11/27 Python
印度民族服装购物网站:BIBA
2019/08/05 全球购物
请问软件开发中的设计模式你会使用哪些
2015/05/13 面试题
简历中求职的个人自我评价
2013/12/03 职场文书
关于赌博的检讨书
2014/01/08 职场文书
给儿子的表扬信
2014/01/15 职场文书
教师节演讲稿
2014/05/06 职场文书
社区助残日活动总结
2014/08/29 职场文书
党政领导班子群众路线对照检查材料
2014/10/26 职场文书
CSS3 制作精美的定价表
2021/04/06 HTML / CSS