Taro實戰-快速開發「知乎」小程序多端應用

npm run dev:h5

# 或 僅限全局安裝

taro build --type h5 --watch

5. 開發前注意

若使用 微信小程序預覽模式 ,則需下載並使用微信開發者工具添加項目進行預覽,此時需要注意微信開發者工具的項目設置 需要設置關閉ES6轉ES5功能,開啟可能報錯

需要設置關閉上傳代碼時樣式自動補全,開啟可能報錯

* 需要設置關閉代碼壓縮上傳,開啟可能報錯

Taro實戰-快速開發「知乎」小程序多端應用

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(, document.getElementById('app'))

6.2 首頁

頁面效果如下:

Taro實戰-快速開發「知乎」小程序多端應用

功能描述:上滑刷新,下拉加載更多,數據請求,點擊跳轉

刷新及繼續加載的動作, 依靠的是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 (

{this.props.feed_source_name}{this.props.feed_source_txt}

{this.props.question}

{this.props.answer_ctnt}

{this.props.good_num} 贊同

{this.props.comment_num} 評論

關注問題

)

}

}

在使用的組件的時候,想使用{...item}的方式來解構賦值,發現也暫時不支持,內心有點奔潰。

Taro實戰-快速開發「知乎」小程序多端應用

不過所幸的是,作者的錯誤提醒很人性化,沒有讓我在這裡浪費很多時間調試,於是我就老老實實一個一個賦值啦。

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 切換功能

Taro實戰-快速開發「知乎」小程序多端應用

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目前的事件綁定不支持匿名函數

// 不支持

this.navigateTo('/pages/answer/answer')} >

  • 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地址。


分享到:


相關文章: