vm模式的核心就是数据变化驱动视图更新,其中关键的一点就是,咱们如何能知道数据发生了变化?框架
经过事件的发布/监听的模式来实现数据监听. 即数据变化后,发布者会触发自定义的某个事件好比valueChage
,而后订阅者捕获到这个事件后,实现后续处理(值判断/视图更新/其余自定义逻辑
). 这其实就是最简单的事件处理的机制优化
待补充this
监测数据的变化还有一种简单且较为完美的实现,而且目前十分火热的Vm框架Vue也是应用了这种方式.那就是Es5中对对象的新增的扩展方法Object.defineProperty()
. 它带来了无数可能性.经过对对象的属性设置改方法,咱们也能轻易的实现数据变化后的逻辑处理.code
先来简单看一看Object.defineProperty()的简单使用对象
Object.defineProperty(obj, prop, descriptor)
var obj = {}; Object.defineProperty(obj, "name", { enumerable: true, configurable: true, get: function () { console.log('get#'); return name; }, set: function (newValue) { console.log('set#'); name = newValue + "~~~"; } }); obj.name = 'Xie' // set# console.log(obj.name); //get# Xie~~~ obj.name = 'Min' // set# console.log(obj.name); //get# Min~~~
参数介绍:事件
value:属性的值ip
writable:若是为false,属性的值就不能被重写get
get: 一旦目标属性被访问就会调回此方法,并将此方法的运算结果返回用户input
set:一旦目标属性被赋值,就会调用此方法it
configurable:若是为false,则任未尝试删除目标属性或修改属性如下特性(writable, configurable, enumerable)的行为将被无效化
enumerable:是否能在for...in循环中遍历出来或在Object.keys中列举出来
P.s writeble/value
不能和get/set
共存,由于object不容许有两种访问机制存在.
正是由于get/set这种特性,咱们就能经过设置set方法来完成数据变化->视图更新
的逻辑
<input id='input'> <p id="output"></p>
var obj = {}; $('#input').on('input',function(){ obj.data = $(this).val(); }); Object.defineProperty(obj, "data", { enumerable: true, configurable: true, get: function () { return data; }, set: function (newData) { data = newData; $('#output').text(data); } });
数据变化驱动视图更新
是MVVM模式中VM的核心逻辑,这种模式下的任什么时候候,咱们都不该该直接以操纵DOM节点的方式来改变视图, 而是必须经过改变数据状态的方式,驱动数据状态变化来改变视图(具体方式上面已经提到了,捕获valueChage事件/SET
等) Angular/Vue/Avalone/等等之类的MVVM框架,就是封装并优化了这一个步骤.