<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
<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:項目開發分支
目錄結構
├── .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 開發工具 @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 `文件名`