Security News
Weekly Downloads Now Available in npm Package Search Results
Socket's package search now displays weekly downloads for npm packages, helping developers quickly assess popularity and make more informed decisions.
在 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';
function modelRegister(register) {
//register model or else
}
function renderApp() {
render(<MVC modelRegister={modelRegister} />, document.getElementById('root'));
}
// start
renderApp();
$ npm i mvc-react
or
$ yarn add mvc-react
首先我们将传统的 MVC 模式与我们的 MVC 模式进行对比。
传统的 MVC 模式:
MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。
mvc-react 与传统的 MVC 模式相比较有几点不同:
mvc-react 与传统的 MVC 模式比较的相同点:
在开发中我们最常做的就是区分模块,Controller 也一样,你可以根据你的需要来划分 controller 的纬度。
在 mvc-react 中,controller 实际上是对路由的高阶抽象,在 controller 中,你可以选择对外开放什么页面以及开放哪些页面。
mvc-react 底层封装了 react-router-controller ,该组件实现了 URL 与 controller 以及对应的 View 的动态映射规则。
使用该功能只需要提前提供一个参数对象给 Controller 的静态 set 方法即可:
Controller.set({
readViewFile(viewId) {
//view可以异步载入
return import(`./view/${viewId}/index.jsx`).then(component => {
return component.default;
});
},
readControllerFile(controllerId) {
//webpackMode: eager是使import变为不异步,跟require一样,
return import(/* webpackMode: "eager" */
`./controller/${controllerId}.js`)
.then(controller => {
return controller.default;
})
},
//设置首页path(跳转路径,即react-router path='/'时,会跳转到indexPath)
indexPath: '/main/index',
});
这样当每次 URL 发生变更时,只要符合映射规则就会执行上述通用流程,并获取对应的 controller ,以及 View 然后展示给用户。
controller 的配置规则如下:
import Controller from 'react-router-controller';
export default class MainController extends Controller {
indexView(params) {
return this.render(
{
title: '主页',
breadcrumbs: [],
},
params
);
}
}
很明显这里采用了类的写法,首先引入基类 Controller
然后写下对外开放的 viewId 对应的方法名,譬如这里对外开放的 viewId 为 index,则对应的方法名为 indexView。更多细节查看该框架的使用入门
mvc-react 底层封装了 redux-saga-model ,每个 model 内都有 reducers
和 sagas
,reducers 中的 reducer 维护 redux 的 model namespace 下的数据块,每个 reducer 都输纯函数,不包括副作用,而 sagas 中的每个 saga 都可以写复杂的副作用。
{
namespace:'index',
state:{
name:'Tim'
},
reducers:{
update:function(state,{payload}){
return{ ...state,name:payload.name };
}
},
sagas:{
*updateName({payload},effects){
yield effects.put({
type:'update',
payload,
});
}
}
}
篇幅有限,这里不对 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'
function modelRegister(register) {
//register model or else
register(model);
}
function renderApp() {
render(<MVC modelRegister={modelRegister} />, document.getElementById('root'));
}
// start
renderApp();
我们只需要在 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';
function modelRegister(register) {
// Controller.set 设置如何读取指定模块的过程
// 譬如如何根据一个 controllerID 加载一个 controller 组件,如何根据一个 viewID 加载一个 view 组件
Controller.set({
readViewFile(viewId, firstLoad) {
if (firstLoad) {
import(/* webpackMode: "eager" */
`./model/${viewId}.js`)
.then(model => {
//注册sagaModel
register(model.default);
});
}
//view 可以异步载入
return import(`./view/${viewId}/index.jsx`).then(component => {
return component.default;
});
},
readControllerFile(controllerId) {
//webpackMode: eager是使import变为不异步,跟require一样,
return import(/* webpackMode: "eager" */
`./controller/${controllerId}.js`)
.then(controller => {
return controller.default;
});
},
//设置首页path(跳转路径,即 react-router path='/'时,会跳转到indexPath)
indexPath: '/main/index',
});
}
function renderApp() {
render(<MVC modelRegister={modelRegister} />, document.getElementById('root'));
}
// start
renderApp();
注意:配置 controller 规则的 Controller.set 方法必须在项目启动时同步执行,不支持异步配置。 modeRegister 是同步执行的,故可以在 modeRegister 回调中放入 Controller.set。
有了上面强大的 Controller 和 Model ,对于 View 而言,我么可以写出非常轻量级的组件,在 react 组件中,当需要触发对应的后续处理时,只需要分发对应的 action 即可,对应 namespace 的 model 会对其进行捕获,并更新数据,重新触发 view 的渲染更新。
import React from 'react';
import { connect } from 'react-redux';
@connect(state => {
return {
display: state.index,
};
})
export default class AboutView extends React.Component {
showToggleEvent = e => {
const { dispatch, display } = this.props;
if (display) {
dispatch({
type: 'index/toggleShow',
payload: false,
});
} else {
dispatch({
type: 'index/toggleShow',
payload: true,
});
}
};
render() {
const { display } = this.props;
return (
<div>
当前位置主页页面:
<button onClick={this.showToggleEvent}>
{display ? '隐藏' : '显示'}
</button>
{display && <div>我被显示了</div>}
</div>
);
}
}
项目打包工具: webpack
项目启动工具:create-react-boilerplate-app
FAQs
mvc-react
The npm package mvc-react receives a total of 2 weekly downloads. As such, mvc-react popularity was classified as not popular.
We found that mvc-react demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Socket's package search now displays weekly downloads for npm packages, helping developers quickly assess popularity and make more informed decisions.
Security News
A Stanford study reveals 9.5% of engineers contribute almost nothing, costing tech $90B annually, with remote work fueling the rise of "ghost engineers."
Research
Security News
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.