01 Taro_Mall 开源多端小程序框架设计

项目介绍

Taro_Mall是一款多端开源在线商城应用程序,后台是基于litemall基础上进行开发,前端采用Taro框架编写,现已全部完成小程序和h5移动端,后续会对APP,淘宝,头条,百度小程序进行适配。Taro_Mall已经完成了 litemall 前端的所有功能

扫码体验

由于小程序没有认证,只发布了一个预览版,只能加15个人,如有需要,请点击小程序申请

小程序 h5移动端

项目架构

项目用Taro做跨端开发框架,Taro基本采用React的写法,项目集成了 redux dva 控制单向数据流,用immer来提供不可变数据,提升整体的性能,减少渲染。

初始化项目

taro init Taro_Mall

进入项目目录开始开发,可以选择小程序预览模式,或者 h5 预览模式,若使用微信小程序预览模式,则需要自行下载并打开微信开发者工具,选择预览项目根目录。

微信小程序编译和发布

yarn dev:weapp  // 编译预览  yarn build:weapp // 构建发布

h5编译和发布

yarn dev:h5  // 编译预览  yarn build:h5 // 构建发布

其它端可以查看package.json 提供的命令

到这里,我们已经把项目初始化完毕,接下来我们引入 dva-core 和 immer,引入dva-core包就可以,不需要引入dva包,dva 包是对 dva-core 和路由,请求库等做了一层封装

yarn add dva-core dva-imme --save

在src 目录下新建 dva.js 文件,文件内容如下, 在创建App的时候,我们把dva-immer插件引入其中。

import {create} from 'dva-core';  import {createLogger} from 'redux-logger';  // import createLoading from 'dva-loading';  import immer from 'dva-immer';    let app;  let store = {};  let dispatch;      function createApp(opt) {    // opt.onAction = [createLogger()];  // 这里可以引入 redux-logger    app = create(opt);    // app.use(createLoading({}));    app.use(immer()); // 引入 immer      if (!global.registered) opt.models.forEach(model => app.model(model));    global.registered = true;    app.start();      store = app._store;    app.getStore = () => store;      dispatch = store.dispatch;      app.dispatch = dispatch;    if (window) {      window.g_app = app;    }    return app;  }    export default {    createApp,    getDispatch() {      return app.dispatch;    },    dispatch: store.dispatch  }  

接下来在入口文件当中引入我们的 dva 文件

import dva from './dva';  import models from './models';    const dvaApp = dva.createApp({    initialState: {},    models: models,    onError(e, dispatch) {      console.log('系统出错了!');      // dispatch(action("sys/error", e));    },  });  const store = dvaApp.getStore();

我们发现dva创建的时候需要引入models,我们在src目录创建models 来存放我们的 model 文件,来管理状态, 我们看下models 文件下的入口文件

import home from './home';  ......    export default [    home,demo, goods, catalog, search       // 导入我们的模块  ]  

我们可以写一个简单的model,例如: demo.js

import delay from '../utils/delay';    export default {    namespace: 'demo',    state: {      list: [],      counter: {        num: 0,      }    },    reducers: {      add: (state, {payload}) => {        state.counter.num ++;      },        dec: (state, {payload}) => {        state.counter.num --;      }      },    effects: {      *asyncAdd(_, {all, call, put}) {        yield call(delay, 2000);//增加延迟测试效果          yield put({type: 'add'});      },    }  };  

接下来,我们要在taro redux的中的Provider传入 store

<Provider store={store}>          <Index />   </Provider>

接下来对请求库做下简单的封装,这里主要封装了对错误消息和统一处理,和提供了get,post方法,如需其它方法,可自行封装

import Taro from '@tarojs/taro';  import {showErrorToast} from '../utils/util';      /**   * 封封微信的的request   */  function request(url, data = {}, method = "GET") {    return new Promise(function(resolve, reject) {      Taro.request({        url: url,        data: data,        method: method,        header: {          'Content-Type': 'application/json',          'X-Litemall-Token': Taro.getStorageSync('token')        },        success: function(res) {            if (res.statusCode == 200) {              if (res.data.errno == 501) {              // 清除登录相关内容              try {                Taro.removeStorageSync('userInfo');                Taro.removeStorageSync('token');              } catch (e) {                // Do something when catch error              }              // 切换到登录页面              Taro.navigateTo({                url: '/pages/auth/login/login'              });            } else if(res.data.errno == 0) {              resolve(res.data.data);            } else {              // Taro.showModal({              //   title: '错误信息',              //   content: res.data.errmsg,              //   showCancel: false              // });              showErrorToast(res.data.errmsg);              reject(res.data.errmsg);            }          } else {            reject(res.errMsg);          }          },        fail: function(err) {          reject(err)        }      })    });  }    request.get = (url, data) => {    return request(url, data, 'GET');  }    request.post = (url, data) => {    return request(url, data, 'POST');  }    export default request;  

现在我们基本就可以用我们熟悉的套路去做开发了

结束语

Taro 遵循 React 语法规范的 多端开发 解决方案。当业务要求同时在不同的端都要求有所表现的时候,针对不同的端去编写多套代码的成本显然非常高,这时候只编写一套代码就能够适配到多端的能力就显得极为需要。

github : Taro_Mall 如果对大家有帮助,请 star 一下