基于react + redux的Bone框架

2,002 阅读3分钟

Bone的使用很简单,上手也很快。如果你想用react搭建一个项目,不妨跟着我试试使用Bone。

Bone特性概述

  • 集成了路由(基于 history.js + react-router),并支持前进、后退状态缓存
  • 使 Component 支持绑定 Model,实现了逻辑与组件分离
  • 提供了灵活的扩展机制( store 可动态修改 reducer 和 middleware )
  • 针对常见开发场景的功能抽象(如 Layout、SSR 等)

安装

  1. 首先需要安装node.js,并且版本要在8.9 LTS 以上

  2. 安装bnpm包管理工具

    bnpm 是Bone应用开发方案的包管理工具,用来安装工具和模块,执行:


        npm install -g bnpm --registry=https://npm.aliplus.com/api
  1. 登录bnpm,执行

        bnpm login

访问 https://bone.aliyun.com/profile ,使用页面上的用户名密码在命令行上登录

  1. 最后安装bone-cli 工具

    bone-cli 是 Bone 提供的本地命令行工具,用来完成项目创建、本地开发和项目打包等功能。执行

         bnpm install -g @bone/bone-cli
    

OK,这样Bone就安装成功了。

创建一个项目

现在我们可以用Bone创建一个项目了,输入

        mkdir 项目名
        cd 项目名
        bone init

我们可以快速创建一个项目,bone start启动这个项目。项目创建成功后,你会看到3个主要的文件分别是app.js,index.html,index.js。app.js可以认为是一个配置路由的地方,index.html就是页面了,而index.js是提供页面组件的文件。通过index.js导出一个组件,然后由app.js引入,通过路由显示出来。

Bone扩展了React.Component 的功能,你可以在Component中的生命周期函数和方法中通过this访问以下属性。

  • navigation

    提供路由导航功能。通过this.navigation.push(path,[state])可以跳转到新的路径并且传递参数。

  • location

    当前的路由信息,通过this.location.pathname可以得到当前路径名。this.location.state可以获取navigation传递过来的参数。

  • layout

    指向当前页的 Layout 实例。通过layout,我们可以实现一些公共组件例如header,footer的重复使用。只需要在app.js中配置layout,这样每个页面都能使用它了。举个例子我们有一个导航栏组件叫 MyLayout,你只需在app.js中配置

      export default createApp({
          appName: "test",
          layout: MyLayout,
          router: {
              routes: [{
              }],
              notFound: NotFound
          }
      })
    

这样你所有的页面都会有这个导航栏了。

  • Model

    在这里着重介绍的是Component 的Model属性,前面Bone的特性中也提到了Model的作用:实现了逻辑与组件的分离。每个组件都可以绑定一个Model,组件可以通过 this.props.xxx 访问 Model 的 state,通过this.actions.xxx 调用 Model 的 action。在下面的例子中,你可以看到Model是如何让逻辑与组件分离的。

    首先我们先看一个未分离的例子

          class Demo extends Component {
              constructor(props) {
                  super(props);
                  this.state = {
                      number : 0
                  };
              }
              add= ()=> {
                  this.setState({ number: this.state.number+ 1});
              }
              render(){
                  return <div className={ style.container }>
                      <h1 className={ style.title }>{this.state.number}</h1>
                      <Button type="normal" onClick={ this.add }>添加</Button>
                  </div>
              }
          }
    

很好理解,就是每次点击一次添加按钮,页面上的数字就加1。这个组件逻辑和组件是未分离的。下面再看分离后是什么样子

        //组件 demo.js
        //引入Model
        import DemoModel from "./demoModel"
        
        class Demo extends Component {
            static Model = DemoModel;
            render(){
                return <div className={ style.container }>
                    <h1 className={ style.title }>{this.props.number}</h1>
                    <Button type="normal" onClick={ this.actions.add }>添加</Button>
                </div>
            }
        }
        
        //Model demoModel.js
        
        export default class DemoModel extends Model {
            // 初始状态
            static initialState = {
                number : 0
            }
            add() {
                return { number: this.state.number+ 1 }
            }
        }

分离后组件和逻辑分别写在2个文件中,组件通过 this.props.number 访问 Model 的state,通过this.actions.add 调用 Model 的 add方法。因为这个例子非常简单,还看不出分离逻辑和组件的好处,但是当你的项目非常复杂的时候,分离的好处就可以提现出来了。

其实Bone框架的好处还有很多,它提供了一套很方便全面的UI库。我用Bone写了一个很简单的demo,上面的代码demo中也有,有兴趣的同学可以下载运行一下看看。附上下载地址 github.com/leslie233/B…