浅谈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 给汉字排序实例代码
Jun 28 Javascript
javascript创建函数的20种方式汇总
Jun 23 Javascript
JS代码实现根据时间变换页面背景效果
Jun 16 Javascript
vue-cli+webpack在生成的项目中使用bootstrap实例代码
May 26 Javascript
node puppeteer(headless chrome)实现网站登录
May 09 Javascript
解决Vue.js由于延时显示了{{message}}引用界面的问题
Aug 25 Javascript
微信小程序实现联动选择器
Feb 15 Javascript
分享一个vue项目“脚手架”项目的实现步骤
May 26 Javascript
移动端吸顶fixbar的解决方案详解
Jul 17 Javascript
vue实现简单加法计算器
Oct 22 Javascript
JS数据类型分类及常用判断方法
Nov 19 Javascript
微信小程序实现锚点跳转
Nov 23 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函数解决SQL injection
2006/12/09 PHP
谈谈PHP的输入输出流
2007/02/14 PHP
PHP的Socket网络编程入门指引
2015/08/11 PHP
深入解析PHP的Yii框架中的缓存功能
2016/03/29 PHP
[原创]网络复制内容时常用的正则+editplus
2006/11/30 Javascript
在javascript将NodeList作为Array数组处理的方法
2010/07/09 Javascript
使用原生js写的一个简单slider
2014/04/29 Javascript
JS中创建函数的三种方式及区别
2016/03/13 Javascript
浅谈js中字符和数组一些基本算法题
2016/08/15 Javascript
性能优化之代码优化页面加载速度
2017/03/01 Javascript
JavaScript使用链式方法封装jQuery中CSS()方法示例
2017/04/07 jQuery
jQuery初级教程之网站品牌列表效果
2017/08/02 jQuery
详解react-native WebView 返回处理(非回调方法可解决)
2018/02/27 Javascript
vue计算属性和监听器实例解析
2018/05/10 Javascript
微信小程序自定义单项选择器样式
2019/07/25 Javascript
jQuery实现input[type=file]多图预览上传删除等功能
2019/08/02 jQuery
Vue+ElementUI使用vue-pdf实现预览功能
2019/11/26 Javascript
微信小程序开发(二):页面跳转并传参操作示例
2020/06/01 Javascript
解决Vue-cli3没有vue.config.js文件夹及配置vue项目域名的问题
2020/12/04 Vue.js
vue项目如何监听localStorage或sessionStorage的变化
2021/01/04 Vue.js
使用PYTHON接收多播数据的代码
2012/03/01 Python
对Python中实现两个数的值交换的集中方法详解
2019/01/11 Python
基于python历史天气采集的分析
2019/02/14 Python
python在新的图片窗口显示图片(图像)的方法
2019/07/11 Python
Python 使用 environs 库定义环境变量的方法
2020/02/25 Python
基于python 取余问题(%)详解
2020/06/03 Python
使用TensorBoard进行超参数优化的实现
2020/07/06 Python
智利最大的网上商店:Linio智利
2016/11/24 全球购物
Oracle快照(snapshot)
2015/03/13 面试题
金融专业推荐信
2013/11/14 职场文书
治安消防安全责任书
2014/07/23 职场文书
关于运动会广播稿200字
2014/10/08 职场文书
2015年科普工作总结
2015/07/23 职场文书
2017大学生寒假社会实践心得体会
2016/01/14 职场文书
python实现简单反弹球游戏
2021/04/12 Python
linux下安装redis图文详细步骤
2021/12/04 Redis