切图崽的自我修养-[MVVM] 如何监听数据变化

数据监听

vm模式的核心就是数据变化驱动视图更新,其中关键的一点就是,我们如何能知道数据发生了变化?

发布-订阅模型

通过事件的发布/监听的模式来实现数据监听. 即数据变化后,发布者会触发自定义的某个事件比如valueChage,然后订阅者捕获到这个事件后,实现后续处理(值判断/视图更新/其他自定义逻辑). 这其实就是最简单的事件处理的机制

待补充


GET/SET

监测数据的变化还有一种简单且较为完美的实现,并且目前十分火热的Vm框架Vue也是应用了这种方式.那就是Es5中对对象的新增的扩展方法Object.defineProperty(). 它带来了无数可能性.通过对对象的属性设置改方法,我们也能轻易的实现数据变化后的逻辑处理.

先来简单看一看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:属性的值

  • writable:如果为false,属性的值就不能被重写

  • get: 一旦目标属性被访问就会调回此方法,并将此方法的运算结果返回用户

  • set:一旦目标属性被赋值,就会调用此方法

  • 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框架,就是封装并优化了这一个步骤.

相关推荐