用 React 編寫的基於Taro + Dva構建的適配不一樣端(微信小程序、H五、React-Native 等)的時裝衣櫥

<img src="http://static-r.msparis.com/uploads/banners/2/a/2aa5a9ecba9d1f4ebad143902c8c1ceb.jpg!w750" width="100%"/>css

前言

Taro 是一套遵循 React 語法規範的 多端開發 解決方案。現現在市面上端的形態多種多樣,Web、React-Native、微信小程序等各類端大行其道,當業務要求同時在不一樣的端都要求有所表現的時候,針對不一樣的端去編寫多套代碼的成本顯然很是高,這時候只編寫一套代碼就可以適配到多端的能力就顯得極爲須要。html

使用 Taro,咱們能夠只書寫一套代碼,再經過 Taro 的編譯工具,將源代碼分別編譯出能夠在不一樣端(微信小程序、H五、React-Native 等)運行的代碼。react

該項目基於Taro,構建了一個時裝衣櫥的項目演示,涉及了一個電商平臺完整的業務邏輯和功能點,若是這個項目能駕馭的了,相信大部分公司的其餘React項目也就不在話下。git

效果演示

查看demo請戳這裏(請用chrome手機模式預覽)github

H5版 && 微信小程序版

<img src="https://gitee.com/easytuan/taro-msparis/raw/master/screenshots/qr-code.png" width="250"/> <img src="https://gitee.com/easytuan/taro-msparis/raw/master/screenshots/weapp-code.jpg" width="250"/>chrome

技術棧

React + Taro + Dvanpm

項目運行

git clone git@github.com:EasyTuan/taro-msparis.git

# 國內鏡像加速節點:git@gitee.com:easytuan/taro-msparis.git

cd taro-msparis

npm install

# 開發時時監聽編譯小程序
npm run dev:weapp

# 開發時時監聽編譯H5
npm run dev:h5

# pages模版快速生成
npm run tep `文件名`

項目說明

git分支說明:json

init:框架總體結構,不涉及任何業務邏輯redux

master:項目的穩定版本小程序

feature:項目開發分支

目標功能

  • [x] 美衣列表 -- 完成
  • [x] 美衣詳情 -- 完成
  • [x] 登陸、註冊 -- 完成
  • [x] 我的中心 -- 完成
  • [x] 優惠券 -- 完成
  • [x] 衣袋(購物車) -- 完成

業務介紹

目錄結構

├── .temp                  // H5編譯結果目錄
├── .rn_temp               // RN編譯結果目錄
├── dist                   // 小程序編譯結果目錄
├── config                 // Taro配置目錄
│   ├── dev.js                 // 開發時配置
│   ├── index.js               // 默認配置
│   └── prod.js                // 打包時配置
├── screenshots            // 項目截圖,和項目開發無關
├── site                   // H5靜態文件(打包文件)
├── src                    // 源碼目錄
│   ├── components             // 組件
│   ├── config                 // 項目開發配置
│   ├── images                 // 圖片文件
│   ├── models                 // redux models
│   ├── pages                  // 頁面文件目錄
│   │   └── home
│   │       ├── index.js           // 頁面邏輯
│   │       ├── index.scss         // 頁面樣式
│   │       ├── model.js           // 頁面models
│   │       └── service.js        // 頁面api
│   ├── styles             // 樣式文件
│   ├── utils              // 經常使用工具類
│   ├── app.js             // 入口文件
│   └── index.html
├── package.json
└── template.js            // pages模版快速生成腳本,執行命令 npm run tep `文件名`

部分截圖展現

首頁 && 商品詳情

<img src="https://gitee.com/easytuan/taro-msparis/raw/master/screenshots/1.png" width="375px" height="667px" /> <img src="https://gitee.com/easytuan/taro-msparis/raw/master/screenshots/2.png" width="375px" height="667px" />

衣袋 && 個人

<img src="https://gitee.com/easytuan/taro-msparis/raw/master/screenshots/3.png" width="375px" height="667px" /> <img src="https://gitee.com/easytuan/taro-msparis/raw/master/screenshots/4.png" width="375px" height="667px" />

登陸 && 優惠券

<img src="https://gitee.com/easytuan/taro-msparis/raw/master/screenshots/5.png" width="375px" height="667px" /> <img src="https://gitee.com/easytuan/taro-msparis/raw/master/screenshots/6.png" width="375px" height="667px" />

taro的安裝及使用

安裝 Taro 開發工具 @tarojs/cli

使用 npm 或者 yarn 全局安裝,或者直接使用npx

$ npm install -g @tarojs/cli
$ yarn global add @tarojs/cli

使用命令建立模板項目

$ taro init myApp

進入項目目錄開始開發,能夠選擇小程序預覽模式,或者 h5 預覽模式,若使用微信小程序預覽模式,則須要自行下載並打開微信開發者工具,選擇預覽項目根目錄。

微信小程序編譯預覽模式

# npm script
$ npm run dev:weapp
# 僅限全局安裝
$ taro build --type weapp --watch
# npx 用戶也可使用
$ npx taro build --type weapp --watch

H5 編譯預覽模式

# npm script
$ npm run dev:h5
# 僅限全局安裝
$ taro build --type h5 --watch
# npx 用戶也可使用
$ npx taro build --type h5 --watch

RN 編譯預覽模式

# npm script
$ npm run dev:rn
# 僅限全局安裝
$ taro build --type rn --watch
# npx 用戶也可使用
$ npx taro build --type rn --watch

固然到這一步有個大概的骨架,做爲生產開發是不夠的,這時候咱們引入dva

$ npm i dva-core dva-loading --save

新建dva.js

import { create } from 'dva-core';
import { createLogger } from 'redux-logger';
import createLoading from 'dva-loading';

let app;
let store;
let dispatch;

function createApp(opt) {
  // redux日誌
  // opt.onAction = [createLogger()];
  app = create(opt);
  app.use(createLoading({}));

  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;
  return app;
}

export default {
  createApp,
  getDispatch() {
    return app.dispatch;
  }
}

並在入口文件導入

import dva from './utils/dva'
const dvaApp = dva.createApp({
  initialState: {},
  models: models,
});
const store = dvaApp.getStore();

dva集成好了,下面咱們來封裝下request網絡請求吧

import Taro from '@tarojs/taro';
import { baseUrl, noConsole } from '../config';

export default (options = { method: 'GET', data: {} }) => {
  if (!noConsole) {
    console.log(`${new Date().toLocaleString()}【 M=${options.url} 】P=${JSON.stringify(options.data)}`);
  }
  return Taro.request({
    url: baseUrl + options.url,
    data: options.data,
    headers: {
      'Content-Type': 'application/json',
    },
    method: options.method.toUpperCase(),
  }).then((res) => {
    const { statusCode, data } = res;
    if (statusCode >= 200 && statusCode < 300) {
      if (!noConsole) {
        console.log(`${new Date().toLocaleString()}【 M=${options.url} 】【接口響應:】`,res.data);
      }
      if (data.status !== 'ok') {
        Taro.showToast({
          title: `${res.data.error.message}~` || res.data.error.code,
          icon: 'none',
          mask: true,
        });
      }
      return data;
    } else {
      throw new Error(`網絡請求錯誤,狀態碼${statusCode}`);
    }
  })
}

好了,是應該準備pages頁面的開發了,本人比較喜歡umi的目錄結構

pages                  // 頁面文件目錄
    └── home
        ├── index.js           // 頁面邏輯
        ├── index.scss         // 頁面樣式
        ├── model.js           // 頁面models
        └── service.css        // 頁面api

一個page要生成4個文件?可否用腳本幫咱們自動生成呢?那來寫一個吧

/**
 * pages模版快速生成腳本,執行命令 npm run tep `文件名`
 */

const fs = require('fs');

const dirName = process.argv[2];

if (!dirName) {
  console.log('文件夾名稱不能爲空!');
  console.log('示例:npm run tep test');
  process.exit(0);
}

// 頁面模版
const indexTep = `import Taro, { Component } from '@tarojs/taro';
import { View } from '@tarojs/components';
import { connect } from '@tarojs/redux';
import './index.scss';

@connect(({${dirName}}) => ({
  ...${dirName},
}))
export default class ${titleCase(dirName)} extends Component {
  config = {
    navigationBarTitleText: '${dirName}',
  };

  componentDidMount = () => {

  };

  render() {
    return (
      <View className="${dirName}-page">
        ${dirName}
      </View>
    )
  }
}
`;

// scss文件模版
const scssTep = `@import "../../styles/mixin";

.${dirName}-page {
  @include wh(100%, 100%);
}
`;

// model文件模版
const modelTep = `import * as ${dirName}Api from './service';

export default {
  namespace: '${dirName}',
  state: {

  },

  effects: {
    * effectsDemo(_, { call, put }) {
      const { status, data } = yield call(${dirName}Api.demo, {});
      if (status === 'ok') {
        yield put({ type: 'save',
          payload: {
            topData: data,
          } });
      }
    },
  },

  reducers: {
    save(state, { payload }) {
      return { ...state, ...payload };
    },
  },

};
`;


// service頁面模版
const serviceTep = `import Request from '../../utils/request';

export const demo = (data) => {
  return Request({
    url: '路徑',
    method: 'POST',
    data,
  });
};
`;



fs.mkdirSync(`./src/pages/${dirName}`); // mkdir $1
process.chdir(`./src/pages/${dirName}`); // cd $1

fs.writeFileSync('index.js', indexTep);
fs.writeFileSync('index.scss', scssTep);
fs.writeFileSync('model.js', modelTep);
fs.writeFileSync('service.js', serviceTep);

console.log(`模版${dirName}已建立,請手動增長models`);

function titleCase(str) {
  const array = str.toLowerCase().split(' ');
  for (let i = 0; i < array.length; i++) {
    array[i] = array[i][0].toUpperCase() + array[i].substring(1, array[i].length);
  }
  const string = array.join(' ');
  return string;
}

process.exit(0);

如今是時候進行愉快的開發了。。。

目錄結構

├── .temp                  // H5編譯結果目錄
├── .rn_temp               // RN編譯結果目錄
├── dist                   // 小程序編譯結果目錄
├── config                 // Taro配置目錄
│   ├── dev.js                 // 開發時配置
│   ├── index.js               // 默認配置
│   └── prod.js                // 打包時配置
├── screenshots            // 項目截圖,和項目開發無關
├── src                    // 源碼目錄
│   ├── components             // 組件
│   ├── config                 // 項目開發配置
│   ├── images                 // 圖片文件
│   ├── models                 // redux models
│   ├── pages                  // 頁面文件目錄
│   │   └── home
│   │       ├── index.js           // 頁面邏輯
│   │       ├── index.scss         // 頁面樣式
│   │       ├── model.js           // 頁面models
│   │       └── service.js         // 頁面api
│   ├── styles             // 樣式文件
│   ├── utils              // 經常使用工具類
│   ├── app.js             // 入口文件
│   └── index.html
├── package.json
└── template.js            // pages模版快速生成腳本,執行命令 npm run tep `文件名`

寫在最後

項目完整代碼地址

文檔

Taro開發文檔

https://nervjs.github.io/taro/docs/README.html

dva開發文檔地址

https://dvajs.com/

小程序開發文檔

https://mp.weixin.qq.com/debug/wxadoc/dev/

相關文章
相關標籤/搜索