MVVM 是指 Model 和 View 通过 ViewModel 连接,形成前端数据流1。ViewModel 提供的是对 MV 的绑定,从语义上和控制器完全不同。

各种框架实现不同,但是主要就是绑定 DOM 事件,监听模型数据,然后中间通过发布订阅沟通,完成数据同步。

前端最早的 MVVM 框架是 Knockout,相比现在的 MVVM 糅合了虚拟 DOM,组件化这样的工程化技术,他就非常轻量;先是注册订阅的回调,绑定 DOM 元素的变更事件,然后在绑定元素变化时,发布一个变更请求,而后有关的回调会被调用更新数据,计算依赖项(计算属性)。

Knockout 只是稍微封装了一下,比起数据驱动,更像是事件驱动;而 Angular 又给加了一层,事件只是触发同步的策略,之后运行的脏检查,实际上就是遍历整个数据集,找到变化的部分,然后触发监听器。

之后的 ES5 普及,setter/getter 开始替换之前的数据检测方法,React 和 Vue 都是基于这个开发的;写过 Java Bean 的会很熟悉,通过 getName 和 setName 来代理外部操作,进行数据检测和 Hook;而他们正是如此。

而 React 因为设计思想,只支持了单向数据流,不过单向数据绑定的数据更易于跟踪管理和维护,缺点是代码量较多比较啰嗦,双向数据绑定的优缺点和单向绑定正好相反。

也正是因为 setter/getter,所以只会监听 state 属性的变化,对于更新和删除就没办法了,但是后面采用 ES6 的 Proxy 实现,就可以对变量的所有操作进行监听。

1
2
3
4
5
6
7
8
9
10
let state = new Proxy({}, {
get: (o, k) => {console.log(`Get ${k}`), o[k]},
set: (o, k, v) => {console.log(`Set ${k}=${v}`), o[k]=v},
deleteProperty: (o, k) => {console.log(`Del ${k}`), delete o[k]}
});

state.a = {};
state.a;
state.a.b = 1;
delete state.a;

剩下的那些操作,那就是大佬的世界了2。。。我这弱鸡继续看 CSS 去

[1]: React虚拟DOM浅析 | AlloyTeam

[2]: Inside Fiber: 深度解析react新的协调算法


  1. Mvvm 前端数据流框架精讲

  2. Mvvm 前端数据流框架精讲