# 1 MVVM

⚡ 30 秒速记

  • MVVM = Model(数据)+ View(视图)+ ViewModel(自动同步两者的中间层)
  • 相比 MVCController 要手写"取数据 → 更新视图"的胶水代码,ViewModel 把这层自动化了
  • Vue 里的 ViewModel 由响应式系统 + 模板编译 + 虚拟 DOM 共同实现;React 严格说不是 MVVM(它是单向数据流 + 手动触发更新)
  • 真正的价值不是"少写代码",而是让状态成为唯一事实来源,视图永远是状态的函数
  • 代价是要理解框架的追踪边界 —— "数据改了页面没变"就是超出边界的表现

MVVM 通过 ViewModel 连接数据模型与界面,让开发者主要关注数据和业务流转。 相比直接获取 DOM 再更新界面,数据驱动能降低业务逻辑与页面的耦合,数据或界面变化时可以同步到另一侧。其核心是双向绑定,Angular 可通过脏检查发现变化,Vue 则可借助数据劫持和发布订阅触发更新。Object.defineProperty 需要遍历属性且监听数组存在限制,Proxy 可以直接拦截对象并原生监听数组变化。

MVVM 由以下三个内容组成

  • View:界面
  • Model:数据模型
  • ViewModel:作为桥梁负责沟通 ViewModel

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

MVVM 中,UI 是通过数据驱动的,数据一旦改变就会相应的刷新对应的 UIUI 如果改变,也会改变对应的数据。这种方式就可以在业务处理中只关心数据的流转,而无需直接和页面打交道。ViewModel 只关心数据和业务的处理,不关心 View 如何处理数据,在这种情况下,ViewModel 都可以独立出来,任何一方改变了也不一定需要改变另一方,并且可以将一些可复用的逻辑放在一个 ViewModel 中,让多个 View复用这个 ViewModel

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

脏数据检测

当触发了指定事件后会进入脏数据检测,这时会调用 $digest 循环遍历所有的数据观察者,判断当前值是否和先前的值有区别,如果检测到变化的话,会调用 $watch 函数,然后再次调用 $digest 循环直到发现没有变化。循环至少为二次 ,至多为十次。

脏数据检测虽然存在低效的问题,但是不关心数据是通过什么方式改变的,都可以完成任务,但是这在 Vue 中的双向绑定是存在问题的。并且脏数据检测可以实现批量检测出更新的值,再去统一更新 UI,大大减少了操作 DOM 的次数。所以低效也是相对的,这就仁者见仁智者见智了。

数据劫持

Vue 内部使用了 Object.defineProperty() 来实现双向绑定,通过这个函数可以监听到 setget 的事件。

webapp
公众号
开发者导航
切换夜间模式
点击侧边栏上一篇
点击侧边栏下一篇
折叠侧边栏
收起全部