最近一周在改造 公羊閱讀?? Taro 版本適配 h5 端,過程中改改補(bǔ)補(bǔ),好不酸爽。
本文記錄??遇到的問題,希望為有相同需求的哥們??節(jié)約點(diǎn)時間。
Taro 版本:1.3.9。
client_mobile_taro github地址
解決跨域問題
h5 發(fā)請求會報跨域問題,需要使用代理轉(zhuǎn)換請求。
編輯根目錄下的 config/index.js 文件
h5: {
devServer: {
host: 'localhost',
port: 10086,
proxy: {
'/api/v1': {
target: 'http://localhost:8000', // 服務(wù)端地址
changeOrigin: true
}
}
},
}
- 代理前的請求:
http://localhost:10086/api/v1/user - 代理后的請求:
http://localhost:8000/api/v1/user
樣式單位
小程序里規(guī)定 1px = 2rpx,Taro 對于像素(px)有一套自己的規(guī)則。
在 Taro 里可以寫 rpx 作為單位。
- Taro 代碼轉(zhuǎn)小程序代碼:無縫轉(zhuǎn)換為小程序單位;
- Taro 代碼轉(zhuǎn) h5 代碼:無法轉(zhuǎn)換。
// taro
height: 10rpx;
// weapp
height: 10rpx;
// h5
// 無法轉(zhuǎn)換單位
在 Taro 里寫 px 作為單位。
- Taro 代碼轉(zhuǎn)小程序代碼:1px = 1rpx,這一點(diǎn)和小程序文檔里介紹的規(guī)則不一樣;
- Taro 代碼轉(zhuǎn) h5 代碼:會自動將 px 轉(zhuǎn)換為 rem 單位。
// taro
height: 10px;
// weapp
height: 10rpx;
// h5
height: 0.625rem;
在 Taro 里寫 PX (大寫字母)作為單位。
- Taro 代碼轉(zhuǎn)小程序代碼:1PX = 2rpx;
- Taro 代碼轉(zhuǎn) h5 代碼:1PX = 1px。
// taro
height: 10PX;
// weapp
hegiht: 20rpx;
// h5
height: 10px;
實(shí)際開發(fā)中。如果你是將小程序端代碼用 Taro 重寫一遍,直接將小程序里面的樣式文件復(fù)制到 Taro 里,并且將所有的 rpx 替換成 px,即可同時適應(yīng)小程序端和 h5 端。
樣式?jīng)_突
h5 頁面源代碼如下:

可以看到,一個 class="taro_pages" 就是一個頁面,所有頁面都寫在??同一個 html 頁面內(nèi),通過 display: "none" 隱藏暫時不需要的頁面。
so,不同頁面的樣式名(class)如果一樣,頁面之間會互相影響。
官方提供 CSS Module 的寫法來避免樣式名稱重復(fù)的問題,不過個人感覺這樣寫起來很難看。
實(shí)際開發(fā)中,我會將每個樣式都加上該頁面的英文單詞作為前綴。比如頁面書架(shelf)頁面,樣式名稱原本為 class="novel-list",拼接之后就變成 class="shelf_novel-list"。
窗口高度
- 小程序端有頭部導(dǎo)航條和底部導(dǎo)航條,下左圖;
- h5 端默認(rèn)是沒有頭部導(dǎo)航條的,下右圖。

二者實(shí)際存儲內(nèi)容的高度不同,會導(dǎo)致部分頁面變形,可以使用下面??的方法獲取窗體高度自行修改 css 樣式高度。
// utils/common.js
import Taro from '@tarojs/taro'
export function getWindowHeight(showTabBar = true) {
const TAB_BAR_HEIGHT = 50
const NAVIGATOR_HEIGHT = 44
const info = Taro.getSystemInfoSync()
const { windowHeight, statusBarHeight } = 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}px`
}
return `${windowHeight}px`
}
不同端加載不同組件
使用場景:
- 小程序端點(diǎn)擊按鈕會顯示用戶昵稱和頭像;
- H5 里沒有這個 API,二者應(yīng)當(dāng)生成不同的頁面。
方法一:不同端寫不同的組件。下方代碼示例,在 index.js 中引入組件,Taro 會自動根據(jù)不同環(huán)境獲取不同的組件。
|-- shelf
|-- components
|-- header.weapp.js
|-- header.h5.js
|-- index.js
// index.js
import header from './components/header'
方法二:根據(jù) process.env.TARO_ENV 環(huán)境變量,渲染不同子組件。
// index.js
// ....
if (process.env.TARO_ENV === 'weapp') {
// 微信小程序端執(zhí)行邏輯
} else if (process.env.TARO_ENV === 'h5') {
// h5 端執(zhí)行邏輯
} else if (process.env.TARO_ENV === 'rn') {
// react-native 端執(zhí)行邏輯
}
上面兩種方法乍看起來,大多數(shù)人都會選擇第一種,會覺得第二種方法很復(fù)雜。
dk 在實(shí)際開發(fā)中發(fā)現(xiàn):
- 第一種反而更麻煩,組件并不僅僅只是渲染頁面,還要處理按鈕點(diǎn)擊事件,父子組件的狀態(tài)值傳遞等等,并沒有想象中簡單;
- 第二種看起來好像要對每種環(huán)境都做單獨(dú)判斷,實(shí)際開發(fā)中 h5 端和 rn 端的邏輯幾乎是一樣的,也就是只要判斷兩種情況:weapp 端和非 weapp 端即可。
封裝不同的請求方法
使用場景:
- 微信小程序端登錄需要使用 code 去拿 openId,進(jìn)而獲取 token 和 userId,小程序端的登錄操作是隱式的;
- h5 端和 rn 端需要提供登錄、注冊等功能,用戶需要顯式登錄之后,才能進(jìn)行之后的操作。
請求庫封裝必不可少,開發(fā)者不希望每次請求都手動獲取 token,亦或是手動添加請求頭類型,像這種公共操作可以封裝一個請求庫。
參考代碼:request.js
POST 請求無法攜帶參數(shù)
- 小程序端非 GET 請求默認(rèn)會把參數(shù)當(dāng)做 json 傳遞;
- h5 端 官方文檔 上寫著默認(rèn)也是 json 傳遞,實(shí)測并不是。
在瀏覽器 Network 中發(fā)現(xiàn)請求體的 Content-Type 為 text/plain,參數(shù)被當(dāng)做字符串傳遞了。
解決方法:手動設(shè)置請求頭類型。
header: {
'content-type': 'application/json'
}
componentDidShow() 不生效
實(shí)際開發(fā)中,在筆記本電腦上用瀏覽器模擬移動端時 componentDidShow() 都是生效的,代碼部署到線上,在手機(jī)上訪問網(wǎng)站,發(fā)現(xiàn) componentDidShow() 不生效。我測試了百度瀏覽器和谷歌瀏覽器,都不生效。
暫時還沒找到替代的方案,如果你有 componentDidShow() 在 h5 端的替代方案,希望可以留言告知我(email: <span>me@dkvirus.com</span>)
補(bǔ)充:taro 升級到 1.3.14 后 componentDidShow() 生效了。
onPullDownRefresh() 不生效
在 pc 端瀏覽器以及真機(jī)上測試下拉刷新都不生效,并且下拉之后,頁面沒有回去(頭部空白部分)。
