r2-js

0.0.17 • Public • Published

R2手脚架

R2框架(Redux React Framework)主要是基于React、Redux而构建的,其中还是用了react-routerreact-router-reduxreact-reduximmutable.js。同时使用webpack模块加载工具,采用ES62015语法。所有如果要使用本框架,这些知识多多少少都要会点的。同时也使用了Ant Design React组件,生成的页面使用的UI是Ant Design,目前只支持这种,后面页面生成也会支持多种UI组件。 R2框架旨在快速搭建页面,减少重复工作,减少重复代码,提高开发效率。

特别说明:下面的环境是在mac下搭建的,在windows上会有差异。

安装使用

安装node

由于还没有正式的版本,可以clone或者下载本框架文件,然后运行下面命令。 通过nvm安装node(nvm可以管理多个版本node,可以来回切换,请使用v6.0.0以上)

//安装nvm
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.31.0/install.sh | bash
//安装最新版node,并可以立刻使用node不用重启终端,安装时好像被墙了,通过vpn装成功
nvm install node && nvm alias default node

npm安装如果被墙可以使用淘宝镜像,单不建议使用cnpm,使用cnpm有时候会安装不完全,直接在~/.npmrc中直接配置:

registry=https://registry.npm.taobao.org

安装R2手脚架

npm install r2-cli -g #安装全局r2命令工具 
mkdir xxxx && cd xxxx
r2 init #r2初始化,按提示进行处理 
npm install #等待依赖包安装 
npm start

然后直接在浏览中打开http://localhost:8888/,即可访问。

初始化后的目录

R2/
    + public/                       #初始化是没有的(打包后生成),直接拷贝到服务环境下即可访问 
    - src/                          #框架和应用代码目录 
        index.jsx                   #框架应用入口文件 
        + libs/                     #框架公共接口方法等,如fetch封装等(非公共组件) 
        - common                    #当前项目公共component和设置等 
         + locale        #国际化 
         + components                #公共组件 
         common.js    #公共变量和一些设置 
         function.js    #公共处理方法 
         global.js    #全局变量设置  
         Fetch.js        #基于antd的fetch拓展,可以自行修改 
        - page/                     #页面级代码 
            App.js                  #路由第一层"/"component 
            action.js                 #可自定义的公共actionCreator 
            reducer.js              #可自定义的公共reducer 
            + nopage                #404页面 
            - view                  #各个页面存放位置 
                + layout            #layout文件存放处 
             - main/
             _route.js      #路由设置处 
             .child_routes.js  #自动生成,后面详解 
                - index/            #应用页面demo,参考使用 
                 _route.js          #路由设置处 
                    index.js        #index页面入口文件 
                    action.js       #Redux action,demo action任务定义处,当然也可以没有 
                    reducer.js      #Redux reducer,demo reducer定义处,当然也可以没有 
    - style/                        #样式图片存放处,这个看喜好吧,约定方式 
        + css/                      #css样式 
        + img/                      #图片存放处 
    Gruntfile.js                    #grunt配置文件,根据需要自己拓展配置h打包生成环境 
    server.js                       #启动服务配置文件,开发环境 
    webpack.config.js               #webpack配置,根据需要自己拓展配置,开发环境  
    package.js                      #npm配置文件 
    .babelrc                        #babel设置 
    .gitignore                      #git提交忽略设置 

R2命令

r2中自定义了如下命令

#运行服务 
npm start 
#打包生成生产环境文件 
npm run build 
#智能Route和Reducer生成命令,相当于r2 ac,情况后续说明 
npm run ac

r2-cli命令请参考r2-cli项目

智能构建

经过上面的步骤可以运行看到页面了,现在开始看如何搭建一个新的页面,在搭建页面前先介绍R2框架自带的一些功能。

智能构建route和reducer

何为智能route和reducer,在R2框架中,只要遵循view文件位置约定规则,route和reducer就可以通过命令生成!你没听错,是用r2是不用怎么关注路由和reducer绑定的! 运行一下命令即可

npm run ac  #ac全称auto creator 

不过要注意的是,view文件要按照约定位置放好,R2/src/page/view目录下新建文件夹就属于一个新页面(必须包含文件_route.js,layout是特殊的view,有点不一样),而reducer生成条件是在view目录下新建reducer.js就会被视为新建reducer,强烈建议在当前页面文件夹中新建reducer.js。

_route.js请看下面的基本使用。

reducer.js需要遵守一定格式! reducer.js格式如下:

export function origin(state = {}, action) {
    switch (action.type) {
        case RECIEVEORIGIN:     
        default:
            return state;
    }
}

不要使用下面这样的格式,虽然是没错,但目前r2还不支持智能识别这种格式。

module.exports = {
    origin(state,action){}
}

基本使用

layout模式

layout是特殊的一种view,其实就是react-router中的第二层组件(第一个是"/",本框架是src/page/App.jsx),view是其子组件。以一种layout为例:

layout包括以下必要文件

  • _route.js,用作路由生成,可自行修改,单务必按照以下格式。
'use strict';
var view = function(){
    //这里try在浏览器中是多此一举,在智能路由中,node环境就需要,跳过r2Common未定义异常
    var re; 
    try{
        re = `${r2Common.prefixUrl}`;
    }catch(e){}
    return re;
}
var childRoutes = function(){
    //这里try在浏览器中是多此一举,在智能路由中,node环境就需要,跳过r2Common未定义异常
    var re;
    try{
        re = require('./.child_routes.js');
    }catch(e){}
    return re;
}
var indexRoute = function(){
    //这里try在浏览器中是多此一举,在智能路由中,node环境就需要,跳过r2Common未定义异常
    var re;
    try{
        re = require("src/page/view/index/_route.js");//indexRoute指定位置
    }catch(e){}
    return re;
}
module.exports = {
    path: view(), 
    getComponent(location, cb) {
        require.ensure([], (require) => {
            cb(null, require("./index"))
        },"main")
    },
    indexRoute: indexRoute(),
    childRoutes: childRoutes(),
}

其中r2Common.prefixUrl是公共path部分(详细看下面公共path部分),可自行定义默认为空。如果定义后为/r2访问/会跳转到/r2路由。有点需要注意的是:indexRoute需要自己手动指定位置。

  • index.jsx,传进react-router处理
import React from 'react'
import Component from 'r2/module/ModuleComponent'
import { connect } from 'react-redux'
 
class View extends Component {
    constructor(props){
        super(props);//使用了构造器,必须要super(props)继承 
    }
    render() {
        super.render();//需要继承,本框架做了些处理,不继承,热替换失效。
        return (
            <div>
                { this.props.children || "" }
            </div>
        )
    }
}
var ReduxView = connect((state)=>{
    return {
    };
})(View)
ReduxView.defaultProps = Object.assign({},Component.defaultProps,{
    homeLink: {
        label:<Antd.Icon type="home"/>,
        link:'/',
    },
});
export default ReduxView; 
  • .child_routes.js

    .child_routes.js是个隐藏文件,自动生成。

view模式

view是我们代码开发主要地方,以下是必要文件,action.jsreducer.js看需要。

  • _route.js,可当做二级路由(没layout)或三级路由(有layout),可自行修改,单务必按照以下格式。
'use strict';
var view = function(){
    //这里try在浏览器中是多此一举,在智能路由中,node环境就需要,跳过异常
    var re; 
    try{
        re = `${r2Common.prefixUrl}/about`;
    }catch(e){}
    return re;
} 
//以下配置请参照React-Router官方文档
module.exports = {
    layout: "main",//在这里设置layout,r2自定义的,跟react-router没关系
    path: view(), 
    getComponent(location, cb) {
        require.ensure([], (require) => {
            cb(null, require("./index"))
        },"about")//webpack生成文件命名
    },
}
  • index.jsx代码结构
import React from 'react'
import Component from 'r2/module/ModuleComponent'
 
class View extends Component {
    constructor(props){
        super(props);//使用了构造器,必须要super(props)继承 
    }
    render() {
        super.render();//需要继承,本框架做了些处理,不继承,热替换失效。
        return (
            <div></div>
        )
    }
}
 
var ReduxView = connect((state)=>{
    return {
    };
})(View)
ReduxView.defaultProps = Object.assign({},Component.defaultProps,{
    title: "title设置处",
    breadcrumb:[
        {
            label:'home',
            link: '/',
        },
        {
            label:'导播活动列表',
        },
    ],
});
export default ReduxView; 

设置公共path

假设我们的域名是localhost,平常我们都是直接访问http://localhost就看访问了页面主页。但是也有特殊要求,要在http://localhost/main访问主页,访问http://localhost也跳转到http://localhost/main(当然通过ngnix可以做些特殊处理)。这个功能就是给你设置main的。

通过r2Common.prefixUrl(位置在src/common/common.js)设置,默认为空,如果不为空第一个字符必须是/,如

r2Common.prefixUrl = '/main';//如果只设置为'main',访问时会报404。

设置浏览器标签title

R2框架是通过react default props设置title的, 在页面index.jsx中设置如下

ReduxView.defaultProps = Object.assign({},Component.defaultProps,{
    title: "title设置处",
});

layout切换

layout默认是page/view/layout/main,设置位置为每个view中的_route.js,代码如下。

'use strict';
var view = function(){
    //这里try在浏览器中是多此一举,在智能路由中,node环境就需要,跳过异常
    var re; 
    try{
        re = `${r2Common.prefixUrl}/about`;
    }catch(e){}
    return re;
} 
module.exports = {
    layout: "main",//在这里设置layout
    path: view(), 
    getComponent(location, cb) {
        require.ensure([], (require) => {
            cb(null, require("./index"))
        },"about")
    },
}

当设置为false时或者不设置,就没有layout。

面包屑

面包屑功能稍微特殊点,需要结合layout页面使用,目前的面包写是针对Ant Design UI做处理的。 面包屑默认自带首页,如果需要修改可以在layout组件中的default props修改。

修改layout组件默认的首页:

//此处为layout组件
var ReduxView = connect((state)=>{
    return {
    };
})(View)
ReduxView.defaultProps = Object.assign({},Component.defaultProps,{
    homeLink: {
        label:<Antd.Icon type="home"/>,
        link:'/',
    },
});
module.exports = ReduxView; 

在当前页面组件的index.jsx中设置如下:

ReduxView.defaultProps = Object.assign({},Component.defaultProps,{
    title: "title设置处",
    breadcrumb:[
        {
            //还支持函数
            label:function(params){
                //params是R2从路由参数`:id`中解析处理,以`-`为分隔符。
                //如果当前路由为`/test/page/9_demo`,params = [9,'demo']
                return params[1];
            },
            link: function(parms){
                //同label
                return "test/page/"+params[0]; 
            },
        },
        {
            label:'循环存储查询',
            link: "/test",
        },
        {
            label:'循环存储查询',
        },
    ]
});

展示需要手动在当前的layout组件中添加,位置自定义:

<div className="r2-breadcrumb">
    { this.breadcrumb || "" }
</div>

定义公共actionCreator

R2框架公共actionCreator定义于R2/src/page/action,建议公共的actionCreator就定义在这里(当然你想定义在其他地方也可以)。commonAction代码如下

import * as r2ActionCreator from "r2/actionCreator"
 
let requestPosts = r2ActionCreator.requestPosts; 
let receivePosts = r2ActionCreator.receivePosts; 
export const REQUESTLOGOUT = "REQUESTLOGOUT"
export const RECIEVELOGOUT = "RECIEVELOGOUT"
 
export function logout(successCallback,callbackAllStatus) {
    var url = r2Common.REQUESTURL + "/sop/v1/operators/logout";
    return r2fetch({
        method: 'POST',
        params:{},
        callbackAllStatus,
        successMessage: true,
    }).dispatchFetchOne(url,requestPosts(REQUESTLOGOUT,"logout"),receivePosts(RECIEVELOGOUT,"logout"),successCallback)
}

定义公共reducer

R2框架公共reducer定义于R2/src/page/reducer,建议公共的reducer就定义在这里(当然你想定义在其他地方也可以),然后运行npm run ac进行reducer绑定。代码如下

import * as actionCreator from './action' 
 
export function logout(state = {}, action) {
    switch (action.type) {
        
        case actionCreator.REQUESTLOGOUT: 
        case actionCreator.RECIEVELOGOUT:   
            return Object.assign({}, state,action);
        
        default:
            return state;
    }
}

全局变量定义

目前R2框架的全局变量如下,详细情况API。

  • r2fn,公共常用方法
  • r2ActionCreator,公共actionCreator
  • r2fetch,R2封装的fetch方法
  • r2Common,当前项目公共配置或方法

国际化功能

国际化语言包位置在R2/src/common/locale文件中,index.js文件是默认是当地开发中语言。配置语言位置在R2/src/common/common.js中,如下:

//国际化处理,language未定义就是默认使用./locale/index.js
export const language = require("./locale/en_US")

使用方式如下:

...
return (
    <div>{r2fn.t("主页")}</div>
)
...

locale/index.js

module.exports = [
    "R2框架",
    "主页",
    "关于",
    "这是一个主页页面!",
    "这是一个关于页面!",
]

locale/en_US.js,索引位置要跟上面的一一对应,所以最好以index.js模板进行翻译,注意空格

module.exports = [
    "R2 framework",
    "Home",
    "About",
    "This is a home page!",
    "This is a  about page!",
]

其他的一些特殊模式

为了更好的管理代码,R2框架建议,所有React组件继承r2-js/libs/module/BasicComponent(layout组件式特殊的一种)。之后新的组件包括页面index.jsx组件,数据逻辑处理请全部写在方法dataAdapter中,事件处理写在events中,redux 的dispatch actionCreator写在方法actions中。代码示例如下:

import React from 'react'
import Component from 'r2/module/ModuleComponent'
import { connect } from 'react-redux'
 
class View extends Component {
    constructor(props){
        super(props); 
    }
    
    actions(){
        return {
            getData(){
                this.props.dispatch(actionCreator());
            },
        }
    }
        
    dataAdapter(){
        return {
            sortData(){
                this.props.data.sort((a,b)=>{
                    return b-a;
                })
            },
        } 
    }
    
    events(){
        return {
            handleClick(text){
                return (e)=>{
                    console.debug(text)
                    console.debug(e)
                }
            }
        }
    }
    
    render() {
        super.render();
        this.sortData();
        return (
            <div onClick={this.handleClick("骚年!")}>
                Hello Word!
            </div>
        )   
    }
}
module.exports = View; 

定义在dataAdapter和events中的方法可以被组件this直接访问,R2框架内部做了处理。

FAQ

正在整理。

Readme

Keywords

none

Package Sidebar

Install

npm i r2-js

Weekly Downloads

13

Version

0.0.17

License

none

Last publish

Collaborators

  • nanges