npm run dev:h5
# 或 僅限全局安裝
taro build --type h5 --watch
5. 開發前注意
若使用 微信小程序預覽模式 ,則需下載並使用微信開發者工具添加項目進行預覽,此時需要注意微信開發者工具的項目設置 需要設置關閉ES6轉ES5功能,開啟可能報錯
需要設置關閉上傳代碼時樣式自動補全,開啟可能報錯
* 需要設置關閉代碼壓縮上傳,開啟可能報錯
6. 功能實現詳解
6.1 小程序全局配置
app.json文件用來對微信小程序進行全局配置,決定頁面文件的路徑、窗口表現、設置網絡超時時間、設置多 tab 等。從原來的 app.json 轉化為 Taro 項目的 app.js 幾乎沒有什麼成本,配置基本一致。只是有一點需要注意,靜態圖片資源文件夾要放在src目錄下面,這樣代碼在編譯打包的時候,才會把圖片資源給複製打包過去。我一開始將靜態圖片資源文件夾跟src同層級,然後各種找不到圖片資源,浪費了許多時間。好了,話不多說,看看下面代碼對比,你就清楚這遷移無比輕鬆,轉寫成 React 寫法,看起來也順眼多了。
原微信小程序 app.json (有刪減)代碼如下:
{
'pages':[
'pages/index/index',
'pages/discovery/discovery',
'pages/more/more',
'pages/answer/answer',
'pages/question/question'
],
'window':{
'backgroundTextStyle':'light',
'navigationBarBackgroundColor': '#0068C4',
'navigationBarTitleText': '知乎',
'navigationBarTextStyle':'white',
'enablePullDownRefresh':true
},
'tabBar': {
'color': '#626567',
'selectedColor': '#2A8CE5',
'backgroundColor': '#FBFBFB',
'borderStyle': 'white',
'list': [{
'pagePath': 'pages/index/index',
'text': '首頁',
'iconPath': 'images/index.png',
'selectedIconPath': 'images/index_focus.png'
}, {
'pagePath': 'pages/discovery/discovery',
'text': '發現',
'iconPath': 'images/discovery.png',
'selectedIconPath': 'images/discovery_focus.png'
}, {
'pagePath': 'pages/more/more',
'text': '我的',
'iconPath': 'images/burger.png',
'selectedIconPath': 'images/burger_focus.png'
}]
}
}
轉寫成Taro 代碼如下:
import Taro, { Component } from '@tarojs/taro'
import Index from './pages/index'
import './app.scss'
class App extends Component {
config = {
pages: [
'pages/index/index',
'pages/discovery/discovery',
'pages/more/more',
'pages/answer/answer',
'pages/question/question'
],
window: {
backgroundTextStyle: 'light',
navigationBarBackgroundColor: '#0068C4',
navigationBarTitleText: 'Taro知乎',
navigationBarTextStyle: 'white',
enablePullDownRefresh: true
},
tabBar: {
color: '#626567',
selectedColor: '#2A8CE5',
backgroundColor: '#FBFBFB',
borderStyle: 'white',
list: [{
pagePath: 'pages/index/index',
text: '首頁',
iconPath: './asset/images/index.png',
selectedIconPath: './asset/images/index_focus.png'
},{
pagePath: 'pages/discovery/discovery',
text: '發現',
iconPath: './asset/images/discovery.png',
selectedIconPath: './asset/images/discovery_focus.png'
},
{
pagePath: 'pages/more/more',
text: '我的',
iconPath: './asset/images/burger.png',
selectedIconPath: './asset/images/burger_focus.png'
}]
}
}
render () {
return (
)
}
}
Taro.render(
6.2 首頁
頁面效果如下:
功能描述:上滑刷新,下拉加載更多,數據請求,點擊跳轉
刷新及繼續加載的動作, 依靠的是ScrollView組件,並在組件上綁定 onScrolltoupper 和 onScrolltolower 來綁定滾動到頂部及底部所觸發的事件, 同時 upperThreshold 和lowerThreshold 能夠調整觸發時距邊界的距離。
數據請求 api 使用 Taro.request, 跟wx.request 使用方法基本一致,不同的是 Taro.request 天然支持 promise 化,mock 數據使用 easy-mock 來提供 。
點擊跳轉使用 Taro.navigateTo,跟 wx.navigateTo 也基本一致,在寫跳轉的時候,一開始想用匿名函數的形式寫,發現 Taro 目前還不支持,據說就要支持了,Taro 的迭代速度還是很快的。
將首頁進行頁面重構的時候,遇到最費時間的問題,應該是wxss轉化為scss,Taro 的組件轉化為微信小程序和 web 後,標籤是不一樣的,比如Image組件會變成image或img標籤,然而原來的wxss裡面使用了標籤名來命名 css,這樣一來就造成了微信小程序跟 web 樣式表現不一致。所以不建議使用標籤名命名 css,建議直接用 class。
export default class Index extends Component {
config = {
navigationBarTitleText: '首頁'
}
constructor() {
super(...arguments)
this.state = {
loading:true,
list:[]
}
}
componentDidMount () {
// 獲取遠程數據
this.updateList()
}
updateList() {
Taro.showLoading({title: '加載中'})
Taro.request({
url: 'https://easy-mock.com/mock/5b21d97f6b88957fa8a502f2/example/feed'
}).then(res => {
Taro.hideLoading()
if (res.data.success) {
this.setState({
loading:false,
list:res.data.data
})
}
})
}
appendNextPageList() {
Taro.showLoading({title: '加載中'})
Taro.request({
url: 'https://easy-mock.com/mock/5b21d97f6b88957fa8a502f2/example/feed'
}).then(res => {
Taro.hideLoading()
if (res.data.success) {
this.setState({
list: this.state.list.concat(res.data.data)
})
}
})
}
render () {
return ( scrollY scrollWithAnimation scrollTop='0' lowerThreshold='10' upperThreshold='10' onScrolltoupper={this.updateList} onScrolltolower={this.appendNextPageList} >
{
this.state.loading
?
: this.state.list.map((item,index)=>{
return
}
)
}
}
6.3 Taro 組件
微信小程序的 Component 組件跟Page 頁面的生命週期函函數不一致很讓人頭疼,頁面的生命週期方法有 onLoad、onReady、onUnload 等,而到了組件中則是 created、attached 、ready 等,相比之下 Taro 就比較統一了,不管是頁面還是組件,寫法都跟 React 的生命週期一致,統一的api開發起來也順暢了許多。
然而 Taro 組件目前還是有很多侷限,比如,不支持直接渲染 children, 即不支持 this.props.children;props 不能傳遞jsx;
在抽象組件的時候,主要有以下注意點
* 在寫法上,Taro 組件首字母要大寫並採用駝峰命名法,比如在 wxml裡面的標籤是view、scroll-view、image,在 Taro 要寫成View、ScrollView、Image。Taro 的事件綁定事件綁定都以 on 開頭並採用駝峰命名法
// 小程序代碼
// Taro 代碼
scrollY
scrollWithAnimation
scrollTop='0'
lowerThreshold='10'
upperThreshold='10'
onScrolltoupper={this.upper.bind(this)}
onScrolltolower={this.lower.bind(this)}
>
- 小程序引用本地靜態資源直接在 src 寫上相對路徑,Taro 引用本地靜態資源需要先 import進來再使用,為了讓 h5 部署的時候圖片路徑不出錯,最好把圖片放在服務器上,然後直接寫 http 路徑
// 小程序 引用本地靜態資源
// Taro 引用本地靜態資源
import searchPng from '../../asset/images/search.png'
// ...此處省略無數代碼
// 最好把圖片放在服務器上,然後寫http 路徑
- 遍歷列表的區別,小程序使用模版語言,而 Taro 使用 jsx
// 小程序
...
// Taro 代碼
{
this.state.list.map((item,index)=>{
return
})
}
答案組件在抽象過程中,想直接寫成純函數形式
// 暫不支持這種寫法
const Text = ({ answer }) =>
{answer}
發現目前還不支持,於是老老實實寫成class的形式了:
export default class Feed extends Component {
navigateTo(url) {
Taro.navigateTo({url:url})
}
render() {
return (
)
}
}
在使用的組件的時候,想使用{...item}的方式來解構賦值,發現也暫時不支持,內心有點奔潰。
不過所幸的是,作者的錯誤提醒很人性化,沒有讓我在這裡浪費很多時間調試,於是我就老老實實一個一個賦值啦。
this.state.list.map((item,index) => {
return feed_source_img={item.feed_source_img} feed_source_txt={item.feed_source_txt} question={item.question} answer_ctnt={item.answer_ctnt} good_num={item.good_num} comment_num={item.comment_num} key={index} /> }) 6.4 “發現頁面”的 tab 切換功能 tab切換原理: 在組件上綁定 onClick 事件 改變 this.state.currentNavtab 值,再通過判斷來實現 tab 切換,函數參數傳遞方式為 this.switchTab.bind(this,index),具體代碼如下: export default class Discovery extends Component { constructor() { super(...arguments) this.state = { currentNavtab: 0, navTab: ['推薦', '圓桌', '熱門', '收藏'], } } switchTab(index,e) { this.setState({ currentNavtab: index }); } render () { return ( { this.state.navTab.map((item,index) => { return (
{item}
)
})
}
...
)
}
}
6.5 輪播功能
輪播頁使用了 Swiper 組件,參數跟小程序都是一一對應,具體可以查看詳細文檔,在重構過程也主要是把 wxml 換成 jsx 的形式。
autoplay='true' interval='5000' duration='500'> {this.state.imgUrls.map((item,index) => { return ( ) })}
7. 使用中發現的問題總結
- Taro 的組件轉化為微信小程序跟web後,標籤是不一樣的,比如Image組件會變成image或img標籤,所以不建議使用標籤名命名css,建議直接用 class目前的事件綁定不支持匿名函數
// 不支持
- Taro 組件在 web 端有許多屬性和事件暫不支持運行環境不同,某些 api 需要根據環境不同處理,比如 wx.getUserInfo 在 web 端是不存在的,此時我們需要判斷環境來執行代碼
if (Taro.getEnv() === Taro.ENV_TYPE.WEAPP) {
// 小程序環境
} else if (Taro.getEnv() === Taro.ENV_TYPE.WEB ) {
// WEB(H5)環境
}
- Taro 目前不支持 SVG(畢竟小程序不支持)
- 目前的第三方庫還比較少(畢竟 Taro 剛出來不久,希望接下來社區能出來各種 ui 庫)Taro 組件暫時不支持純函數,不支持解構賦值 {...item}
8. 總結
將該項目遷移到 Taro 成本並不高,絕大多數工作是做語法的變換。Taro採用 React 的寫法寫微信小程序,總體體驗是非常不錯的,有 React 開發經驗的小夥伴相信能很快上手。同一份代碼就能同時支持web端跟小程序端,確實很讓人驚豔,雖然目前 web 端的支持還比較薄弱,但方向是沒有錯的,接下來只是時間問題。期待 Taro 在接下來的表現。最後對該項目有興趣的同學可以下載代碼下來跑一跑 github地址。
閱讀更多 前端小學生 的文章