浅谈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 相关文章推荐
基于jquery ajax 用户无刷新登录方法详解
Apr 28 Javascript
jQuery如何将选中的对象转化为原始的DOM对象
Jun 09 Javascript
JavaScript严格模式禁用With语句的原因
Oct 20 Javascript
jQuery给指定的table动态添加删除行的操作方法
Oct 12 Javascript
Javascript 实现微信分享(QQ、朋友圈、分享给朋友)
Oct 21 Javascript
全面总结Javascript对数组对象的各种操作
Jan 22 Javascript
vuejs绑定class和style样式
Apr 11 Javascript
angular 用拦截器统一处理http请求和响应的方法
Jun 08 Javascript
微信小程序媒体组件详解(视频,音乐,图片)
Sep 19 Javascript
vue项目中使用tinymce编辑器的步骤详解
Sep 11 Javascript
ES6中new Function()语法及应用实例分析
Feb 19 Javascript
JavaScript禁止右击保存图片,禁止拖拽图片的实现代码
Apr 28 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第一次无法获取cookie问题处理
2014/12/15 PHP
PHP防止刷新重复提交页面的示例代码
2015/11/11 PHP
JQuery的Validation插件中Remote验证的中文问题
2010/07/26 Javascript
jQuery设置和获取HTML、文本和值示例
2014/07/08 Javascript
30个经典的jQuery代码开发技巧
2014/12/15 Javascript
JavaScript判断前缀、后缀是否是空格的方法
2015/04/15 Javascript
ES6中的数组扩展方法
2016/08/26 Javascript
vue-cli入门之项目结构分析
2017/04/20 Javascript
深入理解Vue 单向数据流的原理
2017/11/09 Javascript
DatePickerDialog 自定义样式及使用全解
2019/07/09 Javascript
jquery获取并修改触发事件的DOM元素示例【基于target 属性】
2019/10/10 jQuery
通过js实现压缩图片上传功能
2020/02/25 Javascript
Python使用tablib生成excel文件的简单实现方法
2016/03/16 Python
利用ctypes提高Python的执行速度
2016/09/09 Python
在python里从协程返回一个值的示例
2019/02/19 Python
Python 限制线程的最大数量的方法(Semaphore)
2019/02/22 Python
django中上传图片分页三级联动效果的实现代码
2019/08/30 Python
pygame实现烟雨蒙蒙下彩虹雨
2019/11/11 Python
Python continue语句实例用法
2020/02/06 Python
Python的in,is和id函数代码实例
2020/04/18 Python
详解基于 Canvas 手撸一个六边形能力图
2019/09/02 HTML / CSS
伦敦著名的运动鞋综合商店:Footpatrol
2019/03/25 全球购物
护理专业毕业生自我鉴定
2013/10/08 职场文书
大学生旅游业创业计划书
2014/01/29 职场文书
副厂长岗位职责
2014/02/02 职场文书
致200米运动员广播稿
2014/02/06 职场文书
楼面部长岗位职责范本
2014/02/14 职场文书
学生社团文化节开幕式主持词
2014/03/28 职场文书
2014年创先争优活动总结
2014/05/04 职场文书
小学课外活动总结
2014/07/09 职场文书
党员个人自我剖析材料
2014/10/08 职场文书
2015婚礼主持词开场白
2015/05/28 职场文书
骆驼祥子读书笔记
2015/06/26 职场文书
Go 实现英尺和米的简单单位换算方式
2021/04/29 Golang
Python趣味爬虫之用Python实现智慧校园一键评教
2021/05/28 Python
python中的class_static的@classmethod的巧妙用法
2021/06/22 Python