mvc-react
在 react
、redux
、router
的基础上实现新一代 MVC 的一套解决方案,可以摆脱大量繁杂的配置过程。
相关依赖: react-router-controller 、react-router-redux-saga-model、redux-saga-model
初览-第一印象
import React from 'react';import render from 'react-dom';import BrowserMVC as MVC Controller from 'mvc-react'; { //register model or else} { ;} // start;
install
$ npm i mvc-react
or
$ yarn add mvc-react
角色
首先我们将传统的 MVC 模式与我们的 MVC 模式进行对比。
传统的 MVC 模式:
MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。
mvc-react 与传统的 MVC 模式相比较有几点不同:
- 传统的 view 不负责交互逻辑,由 controller 处理交互逻辑并更新 model 数据。 而我们使用了 react 作为我们的 view 层,完全可以在 react 组件中写与用户的交互逻辑。
- 传统的 model 与 view 一样不负责交互逻辑,只负责数据的维护,这里我们使用了 redux-saga-model 的思想,将其作为 model 层。由于 model 中的 saga 拥有极强的流程控制能力( 底层使用的是 redux-saga ),所以我们完全可以把比较复杂的交互逻辑抽取放在 model 层,此时我们的 model 即具有数据维护的能力也具备实现复杂交互逻辑的能力,再进一步的细分我们还可以将 model 细分成两部分( dataModel、viewModel)。
- 传统的 controller 除了实现交互逻辑还负责路由的控制,mvc-react 的 Controller 只实现路由功能不参与其他逻辑 。
mvc-react 与传统的 MVC 模式比较的相同点:
- 当 model 的数据发生了变化时通知 view 进行及时更新。
- 一样是 model 层对数据负责,不同的 model 负责不同纬度亦或不同业务逻辑相关的数据。
mvc-react 的组件交互图:
如何使用
Controller
在开发中我们最常做的就是区分模块,Controller 也一样,你可以根据你的需要来划分 controller 的纬度。
在 mvc-react 中,controller 实际上是对路由的高阶抽象,在 controller 中,你可以选择对外开放什么页面以及开放哪些页面。
mvc-react 底层封装了 react-router-controller ,该组件实现了 URL 与 controller 以及对应的 View 的动态映射规则。
使用该功能只需要提前提供一个参数对象给 Controller 的静态 set 方法即可:
Controller;
这样当每次 URL 发生变更时,只要符合映射规则就会执行上述通用流程,并获取对应的 controller ,以及 View 然后展示给用户。
controller 的配置规则如下:
; { return this; }
很明显这里采用了类的写法,首先引入基类 Controller
然后写下对外开放的 viewId 对应的方法名,譬如这里对外开放的 viewId 为 index,则对应的方法名为 indexView。更多细节查看该框架的使用入门
Model
mvc-react 底层封装了 redux-saga-model ,每个 model 内都有 reducers
和 sagas
,reducers 中的 reducer 维护 redux 的 model namespace 下的数据块,每个 reducer 都输纯函数,不包括副作用,而 sagas 中的每个 saga 都可以写复杂的副作用。
namespace:'index' state: name:'Tim' reducers: { return ...statename:payloadname ; } sagas: *{ effects; }
篇幅有限,这里不对 model 进行细入的讲解,重点讲如何在 mvc-react 中使用上述的这些 model。
我们回看初栏-第一印象中的代码:
import React from 'react';import render from 'react-dom';import BrowserMVC as MVC Controller from 'mvc-react';import model from 'model/index/db.js' { //register model or else ;} { ;} // start;
我们只需要在 mvc 组件中注入一个 modelRegister 回调,即可拿到入参,注册 model 的方法 register
对 model 进行注册。
配合 Controller 中的介绍,我们可以写出动态加载 controller 以及 view 组件的同时动态注册 model 的代码。
import React from 'react';import render from 'react-dom';import BrowserMVC as MVC Controller from 'mvc-react'; { // Controller.set 设置如何读取指定模块的过程 // 譬如如何根据一个 controllerID 加载一个 controller 组件,如何根据一个 viewID 加载一个 view 组件 Controller;} { ;} // start;
注意:配置 controller 规则的 Controller.set 方法必须在项目启动时同步执行,不支持异步配置。 modeRegister 是同步执行的,故可以在 modeRegister 回调中放入 Controller.set。
View
有了上面强大的 Controller 和 Model ,对于 View 而言,我么可以写出非常轻量级的组件,在 react 组件中,当需要触发对应的后续处理时,只需要分发对应的 action 即可,对应 namespace 的 model 会对其进行捕获,并更新数据,重新触发 view 的渲染更新。
import React from 'react';import connect from 'react-redux'; @Component { const dispatch display = thisprops; if display ; else ; }; { const display = thisprops; return <div> 当前位置主页页面: <button => display ? '隐藏' : '显示' </button> display && <div>我被显示了</div> </div> ; }
其他
-
项目打包工具: webpack
-
项目启动工具:create-react-boilerplate-app