Taro 是一套遵循 React 語法規範的 多端開發 解決方案。現現在市面上端的形態多種多樣,Web、React-Native、微信小程序等各類端大行其道,當業務要求同時在不一樣的端都要求有所表現的時候,針對不一樣的端去編寫多套代碼的成本顯然很是高,這時候只編寫一套代碼就可以適配到多端的能力就顯得極爲須要。css
使用 Taro,咱們能夠只書寫一套代碼,再經過 Taro 的編譯工具,將源代碼分別編譯出能夠在不一樣端(微信小程序、H五、React-Native 等)運行的代碼。html
該項目基於Taro,構建了一個時裝衣櫥的項目演示,涉及了一個電商平臺完整的業務邏輯和功能點,若是這個項目能駕馭的了,相信大部分公司的其餘React項目也就不在話下。react
查看demo請戳這裏(請用chrome手機模式預覽)git
React + Taro + Dvagithub
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分支說明:chrome
init:框架總體結構,不涉及任何業務邏輯npm
master:項目的穩定版本json
feature:項目開發分支redux
目錄結構小程序
├── .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 `文件名`
複製代碼
安裝 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 `文件名`
複製代碼