码迷,mamicode.com
首页 > 其他好文 > 详细

MVVM

时间:2019-01-16 23:54:47      阅读:290      评论:0      收藏:0      [点我收藏+]

标签:ges   fun   ext   问题   image   dde   属性   dev   读写   

MVVM由以下三个内容组成

View:视图模板

Model:数据模型

ViewModel:作为桥梁负责沟通View和Model,自动渲染模板

在JQuery时期,如果需要刷新UI时,需要先取到对应的DOM再更新UI,这样数据和业务的逻辑就和页面有强耦合。

在MVVM中,UI是挺数据驱动的,数据一旦改变就会刷新相应的UI,UI变化也会改变相应的数据。这种方式在开发中只需要关心数据的变化,不用直接去操作DOM。并且可以将一些可复用的逻辑放在一个ViewModel中,多个View复用这个ViewModel。

在 MVVM 中,最核心的也就是数据双向绑定,例如 Angluar 的脏数据检测,Vue 的数据劫持,React数据绑定

 

 Angluar 的脏数据检测

当触发了指定事件后进入脏数据检测,这时期会调用$digest循环遍历所有的数据观察者,判断当前值是否和先前的值有区别,如果检测到变化的话,会调用$watch函数,然后再次调用$digest循环直到发现没有变化。所以这个过程可能会循环几次,一直到不再有数据变化发生后,将变更的数据发送到视图,更新页面展现。如果是手动对 ViewModel 的数据进行变更,为确保变更同步到视图,需要手动触发一次“脏值检测”。

脏数据检测虽然需要每次去循环遍历查看是否有数据变化,存在低效的问题,与Vue的双向绑定原理不同,但是脏数据检测能够同时检测出要更新的值,再去统一更新UI,这样也可以减少操作DOM的次数。

 

Vue 的数据劫持

Vue2.0版本内部使用了Object.defineProperty()来实现数据与视图的双向绑定,体现在对数据的读写处理过程中。即Object.defineProperty()中定义的数据set、get函数。

使用Object.defineProperty()实现Vue2.0双向绑定的小demo:

 <div id="app">
      <input type="text" id="input">
      <span id="text"></span>
 </div>
 var obj = {};
 Object.defineProperty(obj, ‘prop‘, {
     get: function() {
         return val;
     },
     set: function(newVal) {
         val = newVal;
         document.getElementById(‘input‘).value = val;
         document.getElementById(‘text‘).innerHTML = val;
     }
 });
 document.addEventListener(‘keyup‘, function(e) {
     obj.prop = e.target.value;
 });

但仅仅如此还是不够的,还需要在适当的时候添加发布订阅。

技术分享图片

如上所述,vue.js通过Object.defineProperty()来劫持各个属性的setter,getter。再结合发布者-订阅者的方式,

发布消息给订阅者,触发相应的监听回调。通过Directives指令去对DOM做封装,当数据发生变化,会通知指令去修改对应的DOM,数据驱动DOM的变化。vue.js还会对操作做一些监听(DOM Listener),当我们修改视图的时候,vue.js监听到这些变化,从而改变数据。这样就形成了数据的双向绑定。

 

技术分享图片

 

MVVM

标签:ges   fun   ext   问题   image   dde   属性   dev   读写   

原文地址:https://www.cnblogs.com/lhh520/p/10280050.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!