原創聲明:本文為作者原創,未經允許不得轉載,經授權轉載需注明作者和出處
前段時間去了廣州參加了關于「微信小程序」的技術沙龍,整場下來收獲頗多。實際上微信小程序剛剛發布
出來的時候就關注,弄了破解了的開發工具,跑了個官方的 Demo。
聽完回來之后就想著挖個相關的坑,正好看到手機上的 「ONE · 一個」。上網找到了 ONE 的接口,打算
搞一個仿照 ONE 官方 APP 的小程序,最后就有了 weapp-one 這個項目。
關于小程序
微信小程序不是 Web 也不是 Native,嘗試之后給我的感覺有點像是 weex。因為之前嘗試 weex 的時候
是下載一個 APP,然后通過應用內掃碼來運行對應的應用。這一點上小程序類似。
在沙龍上有位分享嘉賓有提到,小程序實際上是在 Webview 之上再加上一層原生的組件。例如底部的
tabbar 以及頂部的 navbar 就是原生的。還有小程序的 map 組件,是調用原生的 map 組件。
請求限制
一開始就遇到了問題,ONE 官方的接口是 http 的,而且是 8000 這個端口。微信小程序對發送的請求有
限制,必須是 https(在本地開發可以用 http),而且不能帶端口號。
所以我就使用了比較暴力的方法,把開發工具中對應用來限制的代碼給注釋掉了,反正只是用來體驗一下小
程序開發,所以就無所謂了。
添加頁面
在小程序中添加頁面都需要將路徑添加到 app.json 中的 page 項中,否則會找不到頁面。與 Vue 類似,每個
小程序頁面包含 page.js , page.wxml , page.wxss ,分別對應腳本,模板以及樣式。
還可以添加一個 page.json 對頁面進行單獨配置,比如配置 navigationBarTitleText 來改變導航上的文字顯示,
諸如此類的對頁面的窗口表現配置。
奇怪的組件
view、text
在 wxml 里面寫的是類似 HTML 的標簽,標準的 HTML 標簽是無法使用的。只能使用微信小程序官方的
組件,組件對應有一些屬性或事件可以調用。有類似于 <div> 的 <view> 組件,基本上頁面上的組件都會被
<view> 包裹住。
然后文字方面是使用 <text> ,雖然直接顯示文字也沒什么問題。不過我還是把所有的文字都加上了 <text> 標
簽。
image
說起組件,微信小程序里最讓我不爽的就是 <image> 這個組件了。給這個組件一個圖片地址之后,默認的樣
式不是圖片的大小,而是固定的 300px * 225px。與 HTML 中的 <img> 完全不同,用起來有點不舒服。
<image> 組件還提供了不同顯示方式的 mode,不過用起來還是覺得怪怪的。
audio
音頻播放的話有 <audio> 這個組件,但是這個組件的樣式好像是固定的,類似于在網頁也加上網易云音樂的
外鏈那樣。不過幸好有音頻播放相關的 api 可以用,這樣就可以當用戶觸發某些操作的時候播放音頻,即可
實現播放按鈕點擊后播放音頻。
微信小程序在播放音頻的時候,開發工具上會出現對應的音樂欄,可以對播放的音頻進行播放/暫停。猜猜在
真機上使用時,會在通知欄出現音頻控制。上面會顯示音頻的作者以及歌曲名稱。但是在實際使用中有一點
比較尷尬,使用調用 api 的方式播放音頻沒有設置音頻作者的選項。詳情可以見 音樂播放控制 · 小程序
video
相較與 HTML5 中的 <video> 標簽,微信小程序中的 <video> 組件缺失了很多東西,例如 loop 與 poster 。也就
是說無法在用戶點擊播放按鈕前顯示特定的圖像,只能是顯示視頻最開頭。
<video> 組件同樣有默認的尺寸 300px * 225px,但沒有 <image> 組件中的顯示模式的設置。未全屏狀態下,
在不同的分辨率上,上下或者左右可能會存在黑邊。
特殊的 rpx
微信小程序中有特有的一個尺寸單位 —— rpx,1rpx 表示屏幕寬度的 1/750 大小,也就是說,100% 寬
度就是 750rpx。還有一個會被忽略的尺寸單位 —— rem,與 Web 中的 rem 不同,1rem 表示屏幕寬
度的 1/20 大小。
在高度上使用 rpx 的話,也會根據屏幕的寬度的大小而改變。我更傾向與寬度使用 rpx 而高度使用 rem,
不過其實比較喜歡用 px 來寫樣式,這可能算是一個不好的習慣。
實現滑至最右切換頁面
在仿照 ONE 寫微信小程序的時候遇到了一個問題,使用滑塊視圖組件 <swiper> 去顯示每日圖文,一共 10
個圖文,當滑動至最右時切換到選擇往期列表的頁面。如下圖所示:
但是 <swiper> 組件并沒有提供對應的事件,使用就自己實現了一個。主要是使用滑塊視圖每一次切換視圖時
都會觸發一個 bindchange 事件,還有設置滑塊視圖顯示位置的 current 屬性。
在 <swiper> 組件中添加一個空的 <swiper-item> 子組件,當滑動到這個空的子組件的時候使用 wx.navigateTo 這
個 api 去切換到往期列表這個頁面。同時將滑塊視圖的顯示位置設置到倒數第二個,即最后一個非空的子組
件。
這樣就實現了滑動至最右切換頁面的功能,同時在點擊返回的時候顯示的也是滑塊視圖中的最后一個有內容
的子組件。具體實現代碼如下:
Page({
data: {
current: 0
},
// ……
// more code
handleChange: function (e) {
let current = e.detail.current
let length = this.data.vols.length
if (current === length) {
this.setData({
current: length
})
wx.navigateTo({
url: ‘../history/history?page=index’,
success: () => {
this.setData({
current: length - 1
})
}
})
}
}
})
這里使用了兩次 this.setData 是因為在第二次執行上面的滑動切換頁面再返回的時候,顯示的子組件并不是
最后一個非空的子組件,而是最后的那個空子組件。大概原因是因為第二次執行這個操作的時候, current 并
沒有更新。
所以解決的方案是在每次修改 current 之前修改一次它的值,使得后面修改 current 值時會觸發視圖的更新。