MVVM的实现原理入门了解1-- 数据代理
最近面试都有提到MVVM的实现思想以及实现双向数据绑定的方法 为此查找对应资源 [https://github.com/DMQ/mvvm]
查看了很多资源都说双向数据绑定有以下方法
- 发布者-订阅者模式
- 脏值查询
- 数据劫持
查看对应资源代码发现 该资源的数据绑定 使用的是数据劫持与Vue的数据绑定相同
为此主要描述我理解的数据劫持实现方法 以及 MVVM实现原理
该资源分为 MVVM.js、observer.js、compile.js、watcher.js等四个文件
主要实现了
- 数据代理 也就是 用 mvvm.xxx = mvvm.data.xxx
- 数据绑定 也就是使用数据劫持实现数据绑定
- 模板解析 也就是通过对el所绑定的div中的所有元素进行解析v-指令、事件指令与{{}}表达式
MVVM.js
function MVVM(options) { this.$options = options || {}; var data = this._data = this.$options.data; var me = this; //进行数据代理 Object.keys(data).forEach(function(key) { me._proxyData(key); }); //进行数据绑定 observe(data, this); //进行模板解析 this.$compile = new Compile(options.el || document.body, this) } MVVM.prototype = { _proxyData: function(key, setter, getter) { var me = this; setter = setter || Object.defineProperty(me, key, { configurable: false, enumerable: true, get: function proxyGetter() { return me._data[key]; }, set: function proxySetter(newVal) { me._data[key] = newVal; } }); } };
MVVM文件理解
创建MVVM构造函数 传入的option为传入的对象 如下面出入的data、el等
var vm = new MVVM({ el: '#mvvm-app', data: { someStr: 'hello ', htmlStr: '<span style="color: #f00;">red</span>', child: { someStr: 'World !' } }, }
- 进行数据存储 将option存储在MVVM的上 也就是this.$options = options || {}; var data = this._data = this.$options.data; var me = this;
- 遍历存储在mvvm上的data中的所有属性 并将属性作为参数传递给MVVM.prototype._proxyData方法 主要用于数据代理
- _proxyData方法 参数1为接收的data中的属性 参数2、3都为自定义的getter、setter方法
- 为每个key也就是data中的属性添加setter 如果形参中有就调用形参的 没有调用object.defineProperty方法
- Object.defineProperty(me, key, { configurable: false, enumerable: true, get: function proxyGetter() { return me._data[key]; }, set: function proxySetter(newVal) { me._data[key] = newVal; } }); 主要功能是为其添加get与set (get为查询时触发、set为数据改变时触发)
- 查询时调用get --> me._data[key];
//使用vm.属性名 读取数据的时候 调用这个方法 // 读取this._data中key的属性值 this指向为mvvm - 数据改变时触发set --> me._data[key] = newVal;
//如果vm.属性名 = newVal 调用这个方法 // 设置this._data中的key的属性值 = newVal
- 查询时调用get --> me._data[key];

浙公网安备 33010602011771号