内容简介:最近要开始搞网页端钱包,本着干一行爱一行的原则,撸起了前端框架。项目基于蚂蚁金服的dva框架,实际上是对几个流行的开源框架的整合,技术栈包括:在开始介绍之前,先说一说MV*。大家一定都听说过MVC,在这之后又衍生出了MVP和MVVM,这些都可以统称为MV*。但是,随着前端代码复杂度的增加,人们发现越来越难以管理程序的状态,模块之间耦合严重,代码难以调试,因此很多人认为“前端MVC已死”。
最近要开始搞网页端钱包,本着干一行爱一行的原则,撸起了前端框架。
项目基于蚂蚁金服的dva框架,实际上是对几个流行的开源框架的整合,技术栈包括:
- react
- react-router
- redux
- redux-saga
- dva
- antd
在开始介绍之前,先说一说MV*。大家一定都听说过MVC,在这之后又衍生出了MVP和MVVM,这些都可以统称为MV*。但是,随着前端代码复杂度的增加,人们发现越来越难以管理程序的状态,模块之间耦合严重,代码难以调试,因此很多人认为“前端MVC已死”。
2014年,facebook提出了一个新的概念:Flux,旨在解决这些问题,其核心思想是“ 组件化 + 单向数据流 ”。这个框架很快流行了起来,并且逐渐成为目前的主流前端框架之一。为了更深刻地理解这一变化,我们来逐一比较一下它们之间的异同:
1.MVC
用户首先通过View发起交互,View调用Controller执行业务逻辑,Controller修改Model,然后View通过观察者模式检测到Model的变化(具体表现形式可以是Pub/Sub或者是触发Events),刷新界面显示。
从这里可以看出,主要业务逻辑都在Controller中,Controller会变得很重。MVC比较明显的缺点:
- View依赖特定的Model,无法组件化
- View和Controller紧耦合,如果脱离Controller,View难以独立应用(功能太少)
2.MVP
为了克服MVC的上述缺点,MVP应运而生。在MVP中,View和Model是没有直接联系的,所有操作都必须通过Presenter进行中转。View向Presenter发起调用请求,Presenter修改Model,Model修改完成后通知Presenter,Presenter再调用View的相关接口刷新界面。这样,View就不需要监听具体Model的变化了,只需要提供接口给Presenter调用就可以了。MVP具有以下优点:
- View可以组件化,不需要了解业务逻辑,只需提供接口给Presenter
- 便于测试:只需要给Presenter mock一个View,实现View的接口即可
3.MVVM
为了进一步解放生产力,把Presenter中调用View的接口同步数据变化的重复工作抽象出来,做成一个binder模块,这就变成了MVVM。开发者只需要指明绑定关系,binder模块会自动完成数据同步,这就是所谓的“ 双向数据流 ”,不管哪一端的数据发生变化,都会立即同步到另一端。实际上,Vue.js、Angular这些流行的前端框架都使用了双向数据流设计。
双向数据流极大地简化了开发者的工作,但是诟病也随之而来。由于绑定的随意性,某个View对Model进行的修改有可能会对其他的View造成“连锁反应”,再加上各种异步回调,给代码调试造成了很大的困难,往往难以定位数据到底是被谁修改掉的。用专业一点的术语来讲,代码的“ 可预测性 ”非常差。因此,为了提高可预测性,很多人主张回归到“单向数据流”模式,其中的典型代表就是facebook的Flux框架。
4.Flux
其实Flux并不是什么新鲜事物,其背后还是经典的MVC思想,但是实现方式上有所不同。Flux的核心是“组件化+单向数据流“,下面逐一进行介绍。
4.1组件化
在传统的MVC设计中,Model中不仅要存储应用程序数据,还需要存储UI状态。另一方面,Controller中不仅要处理业务逻辑,还需要实现各种事件处理逻辑。如果把这部分内容抽出来,和View组合在一起,就变成了“ 组件 ”。这样一来,各个模块都可以各司其职,专注于自己的领域,代码的可读性和复用性都可以得到提高。
在实际编程中,一般把纯界面展示的View实现成一个“ 无状态组件 ”,在其上层再包装一个Controller-View(也可以称为Container),专门监听事件并更新数据,然后把数据作为props传递给View。这种编程模式可以最大程度地提高组件的可复用性。
4.2单向数据流
为了提高代码的可预测性,Flux采用单向数据流设计。这里引入了3个新概念:
- Store:每个程序可以拥有多个Store,存储应用程序状态的不同部分。Store对View是只读的,只有Dispatcher可以通过Store注册的回调函数修改Store的内容
- Action:当发生交互,需要修改Store内容时,需要发起一个Action,包含对应的type和payload
- Dispatcher:当接收到Action时,会通过回调函数调用所有Store的,完成数据修改
当Store数据发生变化时,会发送一个事件,View或者Controller-View可以监听这个事件,然后完成界面刷新。整个过程是“单向”的,如果View想要继续修改Store,必须重新发起一个Action。
当然,除了View以外,服务器或者Web API也可以直接发送Action给Dispatcher,这就是为什么图中Dispatcher有两个输入的原因。
更为详细的Flux流程参见下图:
通过以上分析可以发现,所谓单向数据流并不是什么新鲜概念,实际上最最经典的MVC设计中,数据流就是单向的。虽然Flux官方宣称它们不是MVC,但我个人认为其实它实际想说的是MVVM,因为MVVM才是双向数据流。
当然,Flux也不是完美的,在多Store协同管理上存在一定的设计缺陷,这也是后来Redux出现的原因,且听下回分解。
最后,以一张思维导图结束本篇文章:
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 前端技术演进(一):Web前端技术基础
- 前端技术演进(七):前端跨栈技术
- 前端技术演进(六):前端项目与技术实践
- 前端技术演进(三):前端安全
- 前端技术演进(八):未来前端趋势
- 前端技术演进(五):现代前端交互框架
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。