taro專案初始化及總結
一、專案初始化
npm install -g @tarojs/cli
npm info @tarojs/cli
taro init myApp
cd myApp
yarn install
yarn dev:weapp //h5
由於taro-ui 使用的less 所以css前處理器最好選擇less
二、專案配置
1.配置alias
在config/index.js中增加
import path from 'path';
alias: { '@/components': path.resolve(__dirname, '..', 'src/components'), '@/utils': path.resolve(__dirname, '..', 'src/utils'), '@/service': path.resolve(__dirname, '..', 'src/service'), '@/assets': path.resolve(__dirname, '..', 'src/assets'), '@/config': path.resolve(__dirname, '..', 'src/config'), },
但是在ts檔案中會報紅
需要在 tsconfig.json檔案中的 compilerOptions 中加入
"baseUrl": ".", "paths": { "@/components/*": ["./src/components/*"], "@/utils/*": ["./src/utils/*"], "@/service/*": ["./src/service/*"], "@/assets/*": ["./src/assets/*"], "@/config/*": ["./src/config/*"] },
2. 在專案中使用taro-ui / taro-skeleton
yarn add [email protected]
yarn add taro-skeleton
由於引用 node_modules
的模組,預設不會編譯,所以需要額外給 H5 配置 esnextModules
,在 taro 專案的 config/index.js
中新增如下配置項
h5:{ esnextModules:['taro-ui', 'taro-skeleton'] }
在app.tsx 中引入
import 'taro-ui/dist/style/index.scss' import 'taro-skeleton/dist/index.css'當designWidth 配置為 375 ,taro-ui樣式會被放大
解決辦法:
(1)yarn add postcss-px-scale --save-dev
(2)在config/index.js中新增配置
designWidth: 375, deviceRatio: { 640: 2.34 / 2, 750: 1, 375: 2 / 1, 828: 1.81 / 2, }, mini:{ postcss:{ "postcss-px-scale": { "enable": true, "config": { "scale": 0.5, // 縮放為 1/2 "units": "rpx", "includes": ["taro-ui"] } } } }, h5:{ postcss:{ "postcss-px-scale": { "enable": true, "config": { "scale": 0.5, // 縮放為 1/2 "units": "rem", "includes": ["taro-ui"] } } } }
3.在專案中使用taro-skeleton
import Skeleton from 'taro-skeleton'; const Index = (props: any) => { return ( <Skeleton designWidth={375} {...props} ></Skeleton> ) } export default Index;
4.在專案中使用dva
(1) yarn add dva-core dva-loading --save
(2)yarn add redux react-redux @tarojs/redux @tarojs/redux-h5 redux-thunk redux-logger --save
(3)在utils新建dva.ts 檔案
import { create } from "dva-core"; import { createLogger } from "redux-logger"; import createLoading from "dva-loading"; let app: any; let store: any; let dispatch: any; let registered: any; function createApp(opt) { // redux日誌 opt.onAction = [] if (opt.enableLog) { opt.onAction.push(createLogger()) } app = create(opt) app.use(createLoading()) // 注入model if (!registered) { opt.models.forEach(model => app.model(model)); } registered = true; app.start() // 設定store store = app._store; app.getStore = () => store; app.use({ onError(err: any) { console.log(err); } }) // 設定dispatch dispatch = store.dispatch; app.dispatch = dispatch; return app; } export default { createApp, getDispatch() { return app.dispatch } };
(4)新建models資料夾 新建index.ts. user.ts
//index.ts import user from './user'; export default [ user ]
//user.ts
import Taro from '@tarojs/taro'; import { fetchLogin, fetchUserInfo, fetchUpdateUserInfo } from '@/service/user'; export default { namespace: 'user', state: { token: Taro.getStorageSync('token') || '', openId: Taro.getStorageSync('openId') || '', userInfo: {} }, effects: { *fetchLogin({ payload, callback }, { put, call }) { const _code = Taro.getStorageSync('code'); let data = yield call(fetchLogin, payload); yield put({ type: 'updateState', payload: { token: data.token, openId: data.openid } }) Taro.setStorageSync('token', data.token); Taro.setStorageSync('openId', data.openid); callback && callback() }, *fetchLoginOut({ payload, callback }, { put, call }) { yield put({ type: 'updateState', payload: { token: '', openId: '' } }) Taro.removeStorageSync('token') Taro.removeStorageSync('openId') callback && callback() }, *fetchUpdateUserInfo({ payload, callback }, { put, call }) { let data = yield call(fetchUpdateUserInfo, payload); yield put({ type: 'fetchUserInfo', payload: {} }) callback && callback() } }, reducers: { updateState(state, { payload }) { return { ...state, ...payload } }, updateUserInfo(state, { payload }) { return { ...state, userInfo: { ...state.userInfo, ...payload } } } } }
(5)修改app.js
import React, { Component } from 'react' import Taro from '@tarojs/taro'; import { Provider } from 'react-redux' import dva from '@/utils/dva'; import models from './models'; import 'taro-ui/dist/style/index.scss' import './app.less' import 'taro-skeleton/dist/index.css' const dvaApp = dva.createApp({ initialState: {}, models: models, }) const store = dvaApp.getStore(); class App extends Component { componentDidMount () { } componentDidShow () {} componentDidHide () {} componentDidCatchError () {} // this.props.children 是將要會渲染的頁面 render() { return <Provider store={store}> {this.props.children} </Provider> } } export default App
三、專案中使用的方法 1.獲取不同平臺的視窗高度
export const getPageHeight = (showTabBar = true) => { const NAVIGATOR_HEIGHT = 44 const TAB_BAR_HEIGHT = 50 const info: any = Taro.getSystemInfoSync() const { windowHeight, statusBarHeight, titleBarHeight } = info const tabBarHeight = showTabBar ? TAB_BAR_HEIGHT : 0 if (process.env.TARO_ENV === 'rn') { return windowHeight - statusBarHeight - NAVIGATOR_HEIGHT - tabBarHeight } if (process.env.TARO_ENV === 'h5') { return windowHeight - tabBarHeight } if (process.env.TARO_ENV === 'alipay') { // NOTE 支付寶比較迷,windowHeight 似乎是去掉了 tabBar 高度,但無 tab 頁跟 tab 頁返回高度是一樣的 return windowHeight - statusBarHeight - titleBarHeight + (showTabBar ? 0 : TAB_BAR_HEIGHT) } return windowHeight }
2.複製文字
const handleCopy = (e)=>{ Taro.setClipboardData({ data: logisticNo, success: function () { Taro.getClipboardData({ success: function (res) { console.log(res.data) // data } }) } }) }
3.設定自定義navigationStyle
在頁面index.config,js中
export default definePageConfig({ navigationStyle:'custom' })
4.設定小程式中chekbox自定義樣式
checkbox .wx-checkbox-input { width: 18PX; height: 18PX; border-radius: 50%; border-color: #eee; } checkbox .wx-checkbox-input.wx-checkbox-input-checked { background: #F8C200; border-color: #F8C200; } checkbox .wx-checkbox-input.wx-checkbox-input-checked::before { width: 12PX; height: 12PX; line-height: 12PX; text-align: center; font-size: 12PX; color: #fff; background: transparent; transform: translate(-50%, -50%) scale(1); -webkit-transform: translate(-50%, -50%) scale(1); }
5.iphonex相容樣式
/* iphonex 相容方案 https://aotu.io/notes/2017/11/27/iphonex/index.html */ html, body, #root { height: 100%; overflow: hidden; } /* iphonex 安全區域 */ body { margin: 0; overflow-x: hidden; background-color: #fff !important; padding-bottom: constant(safe-area-inset-bottom); padding-bottom: env(safe-area-inset-bottom); } /* iphonex fix底部元素適配 */ :global(.fixed_bottom) { padding-bottom: constant(safe-area-inset-bottom); padding-bottom: env(safe-area-inset-bottom); position: fixed; z-index: 10; background-color: #fff; }