浅谈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版本A*寻路算法
Dec 22 Javascript
jquery键盘事件使用介绍
Nov 01 Javascript
jQuery动态添加删除select项(实现代码)
Sep 03 Javascript
js中top的作用深入剖析
Mar 04 Javascript
jquery插件tytabs.jquery.min.js实现渐变TAB选项卡效果
Aug 25 Javascript
微信小程序 合法域名校验出错详解及解决办法
Mar 09 Javascript
Vue组件全局注册实现警告框的实例详解
Jun 11 Javascript
微信小程序动态生成二维码的实现代码
Jul 25 Javascript
JavaScript创建对象的常用方式总结
Aug 10 Javascript
IE9 elementUI文件上传的问题解决
Oct 17 Javascript
实现一个 Vue 吸顶锚点组件方法
Jul 10 Javascript
JavaScript适配器模式原理与用法实例详解
Mar 09 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 文件上传代码(限制jpg文件)
2010/01/05 PHP
图文介绍PHP添加Redis模块及连接
2015/07/28 PHP
javascript的document.referrer浏览器支持、失效情况总结
2014/07/18 Javascript
jquery处理json对象
2014/11/03 Javascript
JavaScript中的对象与JSON
2015/07/03 Javascript
浅谈JS继承_寄生式继承 &amp; 寄生组合式继承
2016/08/16 Javascript
JavaScript面向对象编写购物车功能
2016/08/19 Javascript
vue.js实例todoList项目
2017/07/07 Javascript
浅谈关于.vue文件中style的scoped属性
2017/08/19 Javascript
js实现鼠标移动到图片产生遮罩效果
2017/10/21 Javascript
Angular 5.x 学习笔记之Router(路由)应用
2018/04/08 Javascript
一步步教会你微信小程序的登录鉴权
2018/04/09 Javascript
详解单页面路由工程使用微信分享及二次分享解决方案
2019/02/22 Javascript
vue2.0结合Element-ui实战案例
2019/03/06 Javascript
JavaScript函数重载操作实例浅析
2020/05/02 Javascript
javascript+css实现俄罗斯方块小游戏
2020/06/28 Javascript
树莓派中python获取GY-85九轴模块信息示例
2013/12/05 Python
python通过pil模块将raw图片转换成png图片的方法
2015/03/16 Python
总结网络IO模型与select模型的Python实例讲解
2016/06/27 Python
Pyhton中单行和多行注释的使用方法及规范
2016/10/11 Python
Python Tkinter实现简易计算器功能
2018/01/30 Python
python 执行shell命令并将结果保存的实例
2018/05/11 Python
Windows下PyCharm安装图文教程
2018/08/27 Python
Django数据库连接丢失问题的解决方法
2018/12/29 Python
Python流行ORM框架sqlalchemy安装与使用教程
2019/06/04 Python
python 检测nginx服务邮件报警的脚本
2020/12/31 Python
Bitiba意大利:在线宠物商店
2020/10/31 全球购物
经典优秀个人求职自荐信格式
2013/09/25 职场文书
工程安全员岗位职责
2014/03/09 职场文书
文明生主要事迹
2014/05/25 职场文书
中学生2014国庆节演讲稿:不屈的民族
2014/09/21 职场文书
2015年乡镇财政工作总结
2015/05/19 职场文书
2015年思想品德教学工作总结
2015/07/22 职场文书
java项目构建Gradle的使用教程
2022/03/24 Java/Android
使用Nginx的访问日志统计PV与UV
2022/05/06 Servers
Python中的 No Module named ***问题及解决
2022/07/23 Python