项目作者: VonCheng

项目描述 :
集成react + react-router + react-redux的轻量级前端框架。提供keep-live功能,快速构建项目。在构建中大型项目时优势明显。
高级语言: JavaScript
项目地址: git://github.com/VonCheng/Tomatobean.git


Tomatobean

npm

Tomatobean是一个react + redux + react-router的集成框架。它简化了三者的配置,在项目中只需少量代码就能实现复杂的功能,并且能够帮助开发者梳理工程的结构使其易于维护。tomatobean提供了大量的装饰器,为react组件提供更强大的功能。简单的语意,和使用规则让开发者迅速上手开发实现零成本学习。其中创新的使用了智能化自动装载机制,解放了程序员的双手。话不多说开搞。

版本更新历史:

V0.9.0更新文档

Examples:

example—v0.9.2

主要目录如下:

安装" class="reference-link">安装

安装命令:

  1. npm install tomatobean

快速开始" class="reference-link">快速开始

加载配置文件生成App,就像这样

  1. import createApp, { combinModals } from 'tomatobean';
  2. import { routerConfig } from '../config/routerConfig';
  3. import models from './models';
  4. import host from '../config/remoteHost';
  5. const app = createApp();
  6. // 加载路由配置
  7. app.router(routerConfig);
  8. // 加载数据模型
  9. app.model(models);
  10. // 配置remote host
  11. app.setHost(host);
  12. // 运行App
  13. app.run();

app的运行依赖于这三个文件。其中model配置文件涉及到开发者具体项目的业务部分,也是开发者最关系的事情,接下来我会逐一解释这三个文件的用法和作用。

进阶" class="reference-link">进阶

routerConfig" class="reference-link">routerConfig

routerConfig 这个文件主要是配置工程的路由部分。由于tomato框架集成的是react-router组件,所以在配置上跟react-router有一些相似之处。只不过为了一些特殊的功能的实现,再其基础上进行了包装。整个配置文件看起来会是这样。

  1. export const routerConfig = {
  2. routes: [
  3. {
  4. path: '/',
  5. component: 'App',
  6. indexRoute: { redirect: '/home' },
  7. childRoutes: [
  8. {
  9. path: '/home',
  10. component: 'home',
  11. state: {
  12. mark: '首页',
  13. },
  14. },
  15. ],
  16. }, {
  17. path: '/login',
  18. component: 'login',
  19. state: {
  20. checkAuthority: false,
  21. },
  22. },
  23. ],
  24. initializationTabs: [
  25. {
  26. pathname: '/home',
  27. state: {
  28. mark: '首页',
  29. },
  30. },
  31. ],
  32. };

配置规则

  属性名称 | 类型 | 默认值| 描述
—- | —- | — |—-
routes | Object |    | 路由主体
initializationTabs| Object || 初始状态下Tabbar的展示项(可选)
path| string|| 匹配路径
component| string || React页面的放置路径
indexRoute| Object ||需要做重定向的操作对象
redirect| string | |重定向匹配路径
state| object || 浏览器Location的状态,可以在页面跳转的时候最为传值对象。注: 按需要内部可以添加任意多个值,在这里配置作为初始值使用
mark| sting ||是否作为Tabbar的展示项,如果有内容则值作为Tabbar的展示内容(可选)
childRoutes| Object || 子路由
checkAuthority| boolean|true| 需不需要做用户登录认证,也就是说在进入该页面之前是否判断当前用户已登录,没有登录将会跳转登录操作。用户认证的具体配置

models" class="reference-link">models

models作为工程业务的主体部分,也是重点说明的模块。首先还是看一下代码。

  1. // home.js
  2. export default {
  3. namespace: 'home', // 必须唯一 建议与文件名相同
  4. state: {
  5. enters: [],
  6. },
  7. reducers: {
  8. enters(state, action) {
  9. return {
  10. ...state,
  11. enters: action.data.data,
  12. };
  13. },
  14. },
  15. };

一个最为基础的model看起来就是这个样子。你可以把它理解为托管一个React组件状态的机器,或者看做MVC中的M,总之它管控着React组件数据流。

属性说明

属性名称  类型 默认值 描述
namespace string  无   命名空间这里也用做model的名称,需要保证唯一性
state object {} 数据模型,可以理解为需要托管的状态
cache boolean false 缓存类型(与autowrite属性关联)
autowrite object null 设置需要懒加载的state(与cache属性关联)
reducers object {} 存放响应器reducer。响应器是一个用于响应一个action事件,并更新states值的函数。

注:

  1. 当cache: true ,在整个工程范围内,已设置的懒加载state,每条数据只会加载一次,(如果一次没有装载成功,那么接下来的取值还会继续装载,直到装载成功)
    当cache: false,但autowrite有值,那么装载机制的作用范围,就是以绑定模型的组件,而不是整个工程。

  2. reducer是一个用于响应action事件的函数,它被注入了两个参数 stateaction。其中state为当前的所有状态,action参数为action事件传入的值。最后reducer返回一个全新的state。(温馨提示:请参照上方的代码进行理解)

action" class="reference-link">action

action最基础的作用就是发起变更状态的请求。在具体的项目中,你可以将以一些了业务逻辑放在这里,也可以做单纯的数据结构处理。单独作为一个块,这样设计最初的目的也是为了解耦和复用。但多数情况下,actionmodel关系紧密,所以可以将两者放入一个文件中。但同时不要错误的将两者混为一谈。下面就是一个action

  1. // homeAction
  2. import { getEntersListRequest } from '../api/homeApi';
  3. export async function getOpportunityList(params, update) {
  4. const response = await getEntersListRequest(params);
  5. update({
  6. type: 'home/enters',
  7. data: response,
  8. });
  9. return response;
  10. }

action尽量使用async声明,对于异步加载很方便。每一个action都被注入了一个参数updateupdate是一个函数,他只接收一个参数,这个参数是一个对象。其中type为必须属性,它的值指向的是用来响应它请求的,具体某个model下的某个reducer响应器。其他属性为携带参数,可以任意添加。

api" class="reference-link">api

你可以理解为持久层,他负责对接后台服务,也可以想象成数据源。将它但作为一块抽离出来目的是解耦,实现复用。

  1. // 公共接口
  2. import request from '../util/request';
  3. import { urlAppendQuery } from '../util/tools';
  4. /**
  5. * 根据用户Id查询用户信息
  6. */
  7. export async function queryUserByIdRequest() {
  8. return request.GET(`${host}/user-service/user/list`);
  9. }
  10. /**
  11. * 创建用户信息
  12. */
  13. export async function saveUserRequest(params) {
  14. return request.PSOT(`${host}/user-service/save`, params);
  15. }

装饰器" class="reference-link">装饰器

Tomato提供的一些具体的方法、装饰器。这些东西能够为你的组件提供一些特殊的功能,比如:状态回滚、消息通知、路由跳转、location监听等等。

BaseAction" class="reference-link">BaseAction

BaseAction提供基础功能,包括一下方法:

方法 参数 返回值 功能说明
linkTo (location) 跳转
redirect (location) 重定向
go (number) 跳转指定浏览历史记录
goBack 回退
goForward 前进
rollBack (namespace) 组件状态回滚,回到最初状态(仅限于托管的状态)

linkTo" class="reference-link">linkTo

语法

  1. this.props.baseAction.linkTo(location);
  2. // 例子
  3. this.props.baseAction.linkTo("/home");
  4. this.props.baseAction.linkTo({pathname: "/home", state: "hello world"});

参数
location
路由地址信息

返回值

redirect" class="reference-link">redirect

语法

  1. this.props.baseAction.redirect(location);
  2. // 例子
  3. this.props.baseAction.redirect("/home");
  4. this.props.baseAction.redirect({pathname: "/home", state: "hello world"});

参数
location
路由地址信息

返回值

go" class="reference-link">go

语法

  1. this.props.baseAction.go(number);
  2. // 例子
  3. this.props.baseAction.go(1);

参数
number
回退步数

返回值

goBack" class="reference-link">goBack

语法

  1. this.props.baseAction.goBack();

参数

返回值

goForward" class="reference-link">goForward

语法

  1. this.props.baseAction.goForward();

参数

返回值

rollBack" class="reference-link">rollBack

语法

  1. this.props.baseAction.rollBack(namespace);
  2. // 例子
  3. this.props.baseAction.rollBack("home");

参数
modelName
模型的命名空间,也就是模型的名称

返回值

Selecter" class="reference-link">Selecter

绑定modelviewaction三者得工具。由Tomato划分出来的四大模块都是独立的,每一部分都不能独立工组,因为他们不是一个完整的系统。只有通过绑定,引用这些方式,组合在一起才能构成一个完整的组件。

使用实例:

  1. import React, { Component } from 'react';
  2. import { Selecter } from 'tomatobean';
  3. import BaseActions from 'tomatobean/enhance';
  4. import { getOpportunityList } from '../../models/home';
  5. @Selecter(['home'], { getOpportunityList })
  6. export class View extends Component {
  7. componentDidMount() {
  8. const { getOpportunityList } = this.props.actions;
  9. getOpportunityList();
  10. }
  11. render() {
  12. const { enters } = this.props.home;
  13. return (
  14. <div className="home-page">
  15. <p className="group-title">快捷进入</p>
  16. {enters}
  17. </div>
  18. </div>
  19. );
  20. }
  21. }

RootRouteConnect" class="reference-link">RootRouteConnect

标记根路由组件

Configuration" class="reference-link">Configuration

标记当前类为配置类,重写系统的约定配置。

Tabbar" class="reference-link">Tabbar

提供Tabbar数据,如果需要重写Tabber组件,可通过@Tabbar装饰器修饰以获取系统数据。需要注意的是Tomato内部提供了一个Tabber样式组件可直接使用。

Notification" class="reference-link">Notification

通知中心,提供更便捷的通知服务。

Notification通知服务,其中包括一下方法:

方法 参数 返回值 功能说明
observer (name,func) 注册观察者
postNotification (name,…params) 发送消息通知
removeObserver (name) 移除观察者

observer" class="reference-link">observer

语法

  1. const { observer } = this.props.notification;
  2. const active = (message) => {
  3. console.log(message); //打印接收到的消息
  4. ...
  5. }
  6. observer('name', active);

参数
name
观察者名称
active
观察者你收到通知后做出响应

返回值

postNotification" class="reference-link">postNotification

语法

  1. const { postNotification } = this.props.notification;
  2. postNotification('name', message);

参数
name
观察者名称
message
被发送的消息

返回值

removeObserver" class="reference-link">removeObserver

语法

  1. const { removeObserver } = this.props.notification;
  2. removeObserver('name');

参数
name
观察者名称

返回值

配置类" class="reference-link">配置类

AuthorityInterceptor" class="reference-link">AuthorityInterceptor

方法1

方法:static checkAuthority(author, redirect);

用途:是不是有效用户权限(只会在第一次进入系统时是调用);

参数:
@author进入系统的遥控器(此方法可以作为信物传递),只有当 author(true)时才会打开系统。

@redirect重定向方法;

方法2

方法:static preHandle(location, redirect);

用途:每个页面进入之前的预处理(可以在此处做权限控制);

参数:
@location当前访问的地址信息

@redirect重定向方法

@author进入系统的遥控器(此方法可以作为信物传递),只有当 author(true)时才会打开系统。需要注意的是,系统必须存在一个状态,非开即关。所以无论如何author方法必须被调用。

@debut是不是第一次进入系统。

用户登录认证

  1. import { Configuration, AuthorityInterceptor } from 'tomatobean';
  2. @Configuration
  3. export class Ub extends AuthorityInterceptor {
  4. /**
  5. * 是不是有效用户权限
  6. * @param {Func} author 进入系统的遥控器(此方法可以作为信物传递),只有当 author(true)时才会打开系统。
  7. * 需要注意的是,系统必须存在一个状态,非开即关。所以无论如何author方法必须被调用。
  8. * @param {Func} redirect 从定向方法
  9. */
  10. static checkAuthority(author, redirect) {
  11. // 示例代码...
  12. // 模拟异步请求
  13. setTimeout(() => {
  14. if (true) { // 有效用户
  15. author(true);
  16. // 从服务器获取的权限
  17. Ub.AJ = ['/home'];
  18. } else { // 无效用户
  19. author(false);
  20. redirect({ pathname: '/login' });
  21. }
  22. }, 100);
  23. }
  24. /**
  25. * 每个页面进入之前的预处理(可以在此处做权限控制)
  26. * @param {Object} location 当前访问的地址信息
  27. * @param {Func} redirect 重定向方法
  28. * @param {Func} author ...(同上)
  29. * @param {Func} debut 是不是第一次进入系统
  30. */
  31. static preHandle(location, redirect) {
  32. // 示例代码...
  33. if (Ub.AJ && location.pathname === Ub.AJ[0]) {
  34. redirect('/error');
  35. }
  36. }
  37. }

工具方法" class="reference-link">工具方法

1.combinModals

Support" class="reference-link">Support

该框架拥有多个项目的成功案例,如果在项目中开发者遇到问题,可通过下面的联系方式与作者沟通。

联系方式:

wachat: chengpu552877