前端MVVM模式及其在Vue和React中的体现
[TOC]
概述
文章参考:https://segmentfault.com/a/1190000016841537
MVVM相关概念
1) MVVM典型特点是有四个概念:Model、View、ViewModel、绑定器。MVVM可以是单向绑定也可以是双向绑定甚至是不绑定
2) 绑定器:声明性的数据和命令,存在于ViewModel之中,让ViewModel和Model二者进行自动或手动通信,接下来的“MVVM在React中对应关系”小节有举例说明。
3) MVVM本质上是M- V-C-VM,它是在MVC的基础上增加了一层VM,只不过C变弱了,被并入到M概念中,VM用于分离V和M,并且让用户避免由于直接操作V层的DOM而带来的繁琐和效率低下,MVVM使开发更高效,结构更清晰,增加代码的复用性。
4) 在不同的GUI(图形用户界面)上进行展示时,Model、Controller、View-Model能够复用,只需把View层进行替换。
5) 在不同类型的UI(用户界面)上进行展示时,Model、Controller能够复用,只需把View-Model、View层进行替换。比如:假设我们开发的是一款针对盲人的应用,那么输出设备或许我们需要考虑使用扬声器来代替显示器,输入设备使用麦克风,这时我们只需将上述的View-Model替换为Audio-Model作为语音模型,将 V(iew)层替换为Audio层用于播放语音和接收语音输入。
6) 个人认为:在基于MVVM框架的项目中,不管是双向数据绑定还是单向数据绑定,你在开发中实际要面对的都是ViewModel和M(odel)层之前的通信,因为V(iew) 和ViewModel层之间的映射和通信都是由框架自动完成的,
MVVM四层结构
1) M(odel)层:模型,定义数据结构。
2) C(ontroller)层:实现业务逻辑,数据的增删改查。在MVVM模式中一般把C层算在M层中,(只有在理想的双向绑定模式下,Controller 才会完全的消失。这种理想状态一般不存在)
3) ViewModel层:顾名思义是视图View的模型、映射和显示逻辑(如if for等,非业务逻辑),另外绑定器也在此层。ViewModel是基于视图开发的一套模型,如果你的应用是给盲人用的,那么也可以开发一套基于Audio的模型AudioModel。
4) V(iew)层:将ViewModel通过特定的GUI展示出来,并在GUI控件上绑定视图交互事件,V(iew)一般由MVVM框架自动生成在浏览器中。
MVVM在React中对应关系
1) M(odel):对应组件的方法或生命周期函数中实现的业务逻辑和this.state中保存的本地数据,如果React集成了redux +react-redux,那么组件中的业务逻辑和本地数据可以完全被解耦出来单独存放当做M层,如业务逻辑放在Reducer和Action中。
2) V(iew)-M(odel):对应组件中的JSX,它实质上是Virtual DOM的语法糖。React负责维护 Virtual DOM以及对其进行diff运算,而React-dom 会把Virtual DOM渲染成浏览器中的真实DOM
3) View:对应框架在浏览器中基于虚拟DOM生成的真实DOM(并不需要我们自己书写)以及我们书写的CSS。
4)绑定器:对应JSX中的命令以及绑定的数据,如className={ this.props.xxx }、{this.props.xxx}等等。
MVVM的双绑和单绑区别
1) 一般,只有UI表单控件才存在双向数据绑定,非UI表单控件只有单向数据绑定。
2) 单向数据绑定是指:M的变化可以自动更新到ViewModel,但ViewModel的变化需要手动更新到M(通过给表单控件设置事件监听)
3) 双向数据绑定是指念:M的变化可以自动更新到ViewModel,ViewModel的变化也可以自动更新到M
4) 双向绑定 = 单向绑定 + UI事件监听。双向和单向只不过是框架封装程度上的差异,本质上两者是可以相互转换的。
5) 优缺点:在表单交互较多的情况下,单向数据绑定的优点是数据更易于跟踪管理和维护,缺点是代码量较多比较啰嗦,双向数据绑定的优缺点和单向绑定正好相反。
三大框架的异同
1) 三大框架都是数据驱动型的框架
2) vue及angular是双向数据绑定;react是单向数据绑定。React貌似使用的也是Object.defineProperty监控数据,只是没有进一步把表单控件的事件封装进v-model
3) Vuex、Redux都是单项数据绑定的,即M的变化可以自动更新到V,但V的变化必须手动触发事件更新到M,这种单项数据绑定使数据更易于跟踪管理和维护。
4) 未完待续……
Vue双向绑定原理
1) Vue的双向数据绑定是通过Object.defineProperty的get/set对M层数据进行监控,当数据发生变化时,自动更新VM层绑定的数据,而当用户更改了VM层表单控件的数据时,通过v-model自动更新到M层(v-model是对表单控件的事件的封装)