浅谈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,jQuery 排序的实现代码,网页标签排序的实现,标签排序
Apr 27 Javascript
基于jquery的可多选的下拉列表框
Jul 20 Javascript
13 个JavaScript 性能提升技巧分享
Jul 26 Javascript
javascript使用call调用微信API
Dec 15 Javascript
JS+CSS实现闪烁字体效果代码
Apr 05 Javascript
详解JavaScript中双等号引起的隐性类型转换
May 30 Javascript
jQuery查找节点并获取节点属性的方法
Sep 09 Javascript
JS中type=&quot;button&quot;和type=&quot;submit&quot;的区别
Jul 04 Javascript
浅谈Vue.js 关于页面加载完成后执行一个方法的问题
Apr 01 Javascript
webpack自动打包和热更新的实现方法
Jun 24 Javascript
原生js实现抽奖小游戏
Jun 27 Javascript
深入了解JavaScript词法作用域
Jul 29 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
启用Csrf后POST数据时出现的400错误
2015/07/05 PHP
浅析PHP7新功能及语法变化总结
2016/06/17 PHP
Laravel框架中VerifyCsrfToken报错问题的解决
2017/08/30 PHP
thinkphp5引入公共部分header、footer的方法详解
2018/09/14 PHP
PHP进阶学习之命名空间基本用法分析
2019/06/18 PHP
javascript中获取下个月一号,是星期几
2012/06/01 Javascript
jqgrid 表格数据导出实例
2013/11/21 Javascript
基于jQuery实现下拉框
2014/11/24 Javascript
跟我学习javascript的异步脚本加载
2015/11/20 Javascript
JS中使用apply、bind实现为函数或者类传入动态个数的参数
2016/04/26 Javascript
jQuery实现图片向左向右切换效果的简单实例
2016/05/18 Javascript
jquery实现图片跟随鼠标的实例
2017/10/17 jQuery
说说如何在Vue.js中实现数字输入组件的方法
2019/01/08 Javascript
Jquery遍历筛选数组的几种方法和遍历解析json对象,Map()方法详解以及数组中查询某值是否存在
2019/01/18 jQuery
在layui tab控件中载入外部html页面的方法
2019/09/04 Javascript
微信小程序(订阅消息)功能
2019/10/25 Javascript
详解element-ui 表单校验 Rules 配置 常用黑科技
2020/07/11 Javascript
Threejs实现滴滴官网首页地球动画功能
2020/07/13 Javascript
Python使用scrapy采集时伪装成HTTP/1.1的方法
2015/04/08 Python
在Python中操作文件之read()方法的使用教程
2015/05/24 Python
Django REST为文件属性输出完整URL的方法
2017/12/18 Python
python requests post多层字典的方法
2018/12/27 Python
python通过链接抓取网站详解
2019/11/20 Python
selenium+Chrome滑动验证码破解二(某某网站)
2019/12/17 Python
python中Ansible模块的Playbook的具体使用
2020/05/28 Python
Python必须了解的35个关键词
2020/07/16 Python
使用Python将xmind脑图转成excel用例的实现代码(一)
2020/10/12 Python
Marlies Dekkers内衣美国官方网上商店:高端内衣品牌
2018/11/12 全球购物
印尼网上商店:Alfacart.com
2019/03/11 全球购物
个人自我鉴定怎么写
2013/10/28 职场文书
向国旗敬礼活动小结
2014/09/27 职场文书
2014年药房工作总结
2014/11/22 职场文书
2015年团委副书记工作总结
2015/07/23 职场文书
Redis分布式锁Redlock的实现
2021/08/07 Redis
Python Pytorch查询图像的特征从集合或数据库中查找图像
2022/04/09 Python
如何利用python创作字符画
2022/06/25 Python