这里有新鲜出炉的 vue.js 教程,程序狗速度看过来!
Vue.js 是构建 web 界面的 JavaScript 库,提供数据驱动的组件,还有简单灵活的 API,使得 MVVM 更简单。
本篇文章主要介绍了浅谈 vue 实现数据监听的函数 Object.defineProperty,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
在 ES5 中新增了不少新的 API, 例如 新增了 Object.xxx 相关的方法, 其中有一个定义属性相关的 Object.defineProperty 这个方法 (还有 Object.defineProperties) 这个方法是 vue 框架实现数据监听的核心方法, 它的定义如下:
Object.defineProperty([Object] obj, [String] propname, [Object] 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 中操作):
对刚刚的遍历方法还存在一些问题和说明:
1.data 属性的某个属性可能还是对象, 也就是存在多层级对象监听的问题
此时可以使用递归函数遍历 data 的属性, 进行相同操作
2. 通过 data.title = 1 是实际上是调用了 set 方法, 这个类似于 OC 中的点语法
3. 要同时定义多个属性, 可以使用
- Object.defineProperties([Object] obj, [Object] props);
需要注意的是, 本文只是介绍 defineProperty 的基本使用, 并非代表 vue 的代码实现
来源: http://www.phperz.com/article/17/0720/336275.html