# 1 MVVM
⚡ 30 秒速记
MVVM=Model(数据)+View(视图)+ViewModel(自动同步两者的中间层)- 相比
MVC:Controller要手写"取数据 → 更新视图"的胶水代码,ViewModel把这层自动化了 Vue里的ViewModel由响应式系统 + 模板编译 + 虚拟DOM共同实现;React严格说不是MVVM(它是单向数据流 + 手动触发更新)- 真正的价值不是"少写代码",而是让状态成为唯一事实来源,视图永远是状态的函数
- 代价是要理解框架的追踪边界 —— "数据改了页面没变"就是超出边界的表现
MVVM 通过 ViewModel 连接数据模型与界面,让开发者主要关注数据和业务流转。 相比直接获取 DOM 再更新界面,数据驱动能降低业务逻辑与页面的耦合,数据或界面变化时可以同步到另一侧。其核心是双向绑定,Angular 可通过脏检查发现变化,Vue 则可借助数据劫持和发布订阅触发更新。Object.defineProperty 需要遍历属性且监听数组存在限制,Proxy 可以直接拦截对象并原生监听数组变化。
MVVM由以下三个内容组成
View:界面Model:数据模型ViewModel:作为桥梁负责沟通View和Model
在
JQuery时期,如果需要刷新UI时,需要先取到对应的DOM再更新UI,这样数据和业务的逻辑就和页面有强耦合。
在 MVVM 中,UI 是通过数据驱动的,数据一旦改变就会相应的刷新对应的 UI,UI 如果改变,也会改变对应的数据。这种方式就可以在业务处理中只关心数据的流转,而无需直接和页面打交道。ViewModel 只关心数据和业务的处理,不关心 View 如何处理数据,在这种情况下,View 和 Model 都可以独立出来,任何一方改变了也不一定需要改变另一方,并且可以将一些可复用的逻辑放在一个 ViewModel 中,让多个 View复用这个 ViewModel。
- 在
MVVM中,最核心的也就是数据双向绑定,例如Angluar的脏数据检测,Vue中的数据劫持。
脏数据检测
当触发了指定事件后会进入脏数据检测,这时会调用
$digest循环遍历所有的数据观察者,判断当前值是否和先前的值有区别,如果检测到变化的话,会调用$watch函数,然后再次调用$digest循环直到发现没有变化。循环至少为二次 ,至多为十次。
脏数据检测虽然存在低效的问题,但是不关心数据是通过什么方式改变的,都可以完成任务,但是这在
Vue中的双向绑定是存在问题的。并且脏数据检测可以实现批量检测出更新的值,再去统一更新UI,大大减少了操作DOM的次数。所以低效也是相对的,这就仁者见仁智者见智了。
数据劫持
Vue内部使用了Object.defineProperty()来实现双向绑定,通过这个函数可以监听到set和get的事件。