Model-View-ViewModel 模式,最早在 2005 年微软推出的基于 Windows 的⽤户界⾯框架 WPF 中提出,而最早采用 MVVM 的前端框架是 2010 年发布的 Knockout。
Model 层
对应数据层的域模型,主要用来做域模型的同步。
通过 Ajax、fetch 等 API 完成客户端和服务端业务模型的同步。
在分层关系中,它主要⽤于抽象出 ViewModel 层中视图的 Model。
View 层
作为视图模板存在,其实在 MVVM 中整个 View 就是⼀个动态模板。
除了用于定义结构和布局之外,它还展示了 ViewModel 层的数据和状态。
View 层并不负责状态的实际处理,它只是做:数据绑定声明、 指令声明、 事件绑定声明。
ViewModel 层
负责暴露数据给 View 层,并对 View 层中的数据绑定声明、 指令声明、 事件绑定声明进行实际的业务逻辑。
ViewModel 底层会做好绑定属性的监听,当 ViewModel 中的数据变化时,View 层会自动进行更新;⽽当 View 中声明了数据的双向绑定(表单元素),框架也会监听 View 层(表单元素)值的变化,⼀旦变化,则 View 层绑定的 ViewModel 中的数据也会得到⾃动更新。
MVVM的优缺点有哪些?
优点
- 实现了视图(View)和模型(Model)的分离,降低代码耦合、提⾼视图或逻辑的复⽤性
⽐如:View 可以独⽴于 Model 变化和修改,⼀个 ViewModel 可以绑定于不同的 "View",当 View 发生变化时 Model 一定会随之改变,而当 Model 变化时则 View 可以不变。我们可以把⼀些视图逻辑放在⼀个 ViewModel ⾥,以此让多个 View 重⽤这段视图逻辑。
- 提⾼了可测试性:ViewModel 的存在可以帮助开发者更好地编写测试代码
- 能⾃动更新 DOM:利⽤双向绑定,数据更新后视图⾃动更新,让开发者从繁琐的⼿动操作 DOM 中解放出来
缺点
- Bug 很难被调试:因为使⽤了双向绑定的模式,当我们看到界⾯发生异常了,有可能是 View 的代码产生的 Bug,也有可能是Model 代码的问题。数据绑定使得⼀个位置的 Bug 被快速传递到别的位置,要定位原始出问题的地⽅就变得不那么容易了。另外,数据绑定的声明是指令式地写在 View 模版中的,它们没办法打断点进行 Debug
- 在⼀个⼤的模块中 Model 也会很⼤,虽然使⽤上来说⽅便了,也能很容易的保证了数据的⼀致性,但如果⻓期持有不释放内存,就会造成更多的内存消耗
- 对于⼤型的图形应⽤程序,视图状态较多,ViewModel 的构建和维护的成本都会⽐较⾼