NBA總決賽結束還沒一週,立刻世界盃就如期而至。你們在熬夜看球,而我關在小黑屋默默碼字(可憐臉)。在體驗到小程序的方便快捷省內存以後,前段時間的「騎勇大戰」果斷用了小程序觀看。因爲體驗不錯,又正在學習小程序知識,立刻就想動手實踐學習一下「騰訊體育」小程序的製做。到目前爲止,只想說一句「選擇是好的,過程是一言難盡的」,雖然還沒所有完成,但也遇到很多問題,但願此分享能夠給你帶來幫助(源碼)。html
(乾巴巴的開講,還不如先來波動圖)vue
讓咱們先來看看開發文檔git
在此項目中,首頁——世界盃的頭部是一個橫向滑動的scroll-view
組件,在設置了scroll-x
屬性後,並未達到預期效果,scroll-view中的每一個部分仍是自成一行。在一番簡單搜索後得出,設置white-space: nowrap;
樣式就可以使其在同一行。github
NBA賽事詳情頁中有5個sroll-view,雖然內容有點少,但仍是看得出有scroll的效果的。 小程序
一樣的,在製做豎向滾動效果時,須要設置sroll-y
屬性,在官方的文檔中也特別說明了數組
使用豎向滾動時,須要給
scroll-view
一個固定高度,經過 WXSS 設置 height。bash
那麼問題來了,在scroll-view
並不是佔滿全屏的狀況下,如何肯定其高度呢?框架
首先想到,把包含選項卡和scroll-view
的大盒子固定寬度後,在遵循文檔流的狀況下,將 scroll-view
高度設置爲 100%不就行了嗎?可是,在如此一番設置以後,scroll-view
的高度變成了大盒子的高度???(黑人問號臉),最重要的是scroll-view
中的內容不能徹底顯示,這就頭疼了。佈局
隨後立刻想到可使用彈性佈局,固定其選項卡的高度,下方的scroll-view
設置flex: 1
,這難道還解決不了嗎?是的,bug永相隨。下圖能夠看到,選項卡的高度明顯變小,要是scroll-view的內容再多一點,選項卡就被擠到窒息了。 學習
最後無奈只好將scroll-view的高度逐漸調整到屏幕底部的高度,簡直不要太粗暴,缺點是在不一樣屏幕尺寸設備上查看,效果不一。若是有大佬可提供較好解決方案,懇請指教。
開發文檔是好朋友,讓咱們再來看看。
swiper
組件在小程序中很是常見,它可在有限的區域展現更多內容,還能增長頁面的視覺動態效果,總之就是好。(但,好東西也是有槽點的啦)
1) 從上面動圖可看出,NBA賽事詳情頁中也使用到了swiper
組件,而且與頭部的導航進行了綁定,滑動swiper
可改變導航欄的狀態,點擊導航欄選項可切換swiper-item
。這個實現較爲簡單,步驟以下:
data
中添加一個表示下標的變量curIndex
;wx:if
條件渲染,若curIndex
等於當前選項的下標,則在其底部添加一個僞元素表示選中;curIndex
綁定到swiper
的current
屬性中,經過選項卡的bindtap
事件和swiper
的bindchange
事件實時切換swiper-item
。話很少說,貼上代碼:
//nbaMatches.wxml
<view class="info_hd">
<view class="headerMenu {{curIndex===index?'on':''}}"
wx:for="{{nbaMenu}}"
data-index="{{index}}"
bindtap="switchSort">
<view class="nbaSort">{{item.nbaSort}}</view>
</view>
</view>
<view class="info_bd">
<swiper current="{{curIndex}}" bindchange="bindswiper">
...
</swiper>
</view>
複製代碼
//nbaMatches.js
bindswiper(e) {
this.setData({
curIndex: e.detail.current
})
},
switchSort(e) {
console.log(e.currentTarget.dataset.index);
this.setData({
curIndex: e.currentTarget.dataset.index?e.currentTarget.dataset.index: 0
})
}
複製代碼
2)此項目的「熱門」頁也使用了一個swiper
組件,相比普通swiper
的使用,這個更爲複雜。此處的swiper
再也不是與有限個的選項進行交互,而是與無限個的日期進行交互。難道一年365天就要365個swiper-item
? 嚇得老夫虎軀一震。
通過一場「豬腦子」風暴後,仍是沒有想出完美的解決方案,只好設置有限個swiper-item
來初步實現所需效果。
仍是貼代碼吧!
//swiper的bindchange事件
changeMatch(e) {
const current = e.detail.current; //獲取當前位置
const befInd = this.data.swiperCurIndex; //獲取滑動前的位置
const index = current - befInd;
if (index <= -1) { //判斷左滑右滑
this.preDay(); //日期切換至前一天
} else if (index >= 1) {
this.nextDay(); //日期切換至後一天
} else {
return
}
}
複製代碼
// nextDay() 方法相似
preDay() {
let day = this.data.day;
let month = this.data.month;
let week= this.data.week;
let i = this.data.i;
if (i<=0) { //週一至週日的循環切換
i = 6;
}else {
i--;
}
if(day<=1) { //日期本月第一天時,將日期切換至上月最後一天
month--;
day = this.data.daysCountArr[month-1];
}else {
day--; //不然切換至前一天
}
this.setData({
swiperCurIndex: this.data.swiperCurIndex-1,
month,
day,
i,
week: this.data.weekArr[i],
curDate: month+'月'+day+'日'+' '+this.data.weekArr[i]
})
}
複製代碼
若是大佬們有解決方案歡迎交流討論。詳細代碼查看可點擊這裏。
天啦嚕!你連選項卡都要說?(笑哭)聽我解釋。
一般咱們使用的選項卡中的選項都是 2 到 4 個,若是不嫌麻煩,咱們只要將選項卡和其對應的內容逐個在.wxml
中寫出來就行了。可是,一旦選項變多,若逐個寫出,那.wxml
中的代碼將跟「懶婆娘的裹腳布」似的。此時,使用wx:for
來循環輸出選項就很是有必要了。另外,若是每一個選項中的內容都是相似的就更好了,可經過選項卡的點擊事件得到當前選項的id
,根據id
使用wx:if
條件渲染來決定當前選項卡顯示的數據。在這又要cue一下咱們的NBA賽事詳情頁,此頁面中的球員榜這個swiper-item
就包含了一個有 5 個選項的選項卡。
詳細代碼查看可點擊這裏。
爲了更好的體驗,體育賽事總要加入日曆,方便用戶查看賽事安排。若使用picker
組件,用戶體驗可能差強人意,那麼如何自定義一個日曆呢?在參照了各路大神的方法後得出如下分析:
swiper
組件。日曆主體中的每個月日期是一個二維數組,每個月的週數則爲數組的length,所以wxml中的日期輸出須要使用兩重wx:for
。部分代碼以下:<view class="calendar_box" wx:for="{{dateList}}" wx:for-item="week" wx:key="{{index}}" style="{{index==0?'justify-content: flex-end;':''}}">
<view wx:for="{{week}}" data-date="{{item}}"
class="weekday_label {{item.value==selectedDate?'active_label':''}}" bindtap="selectDate">
<view class="date">
<text>{{item.date}}</text>
</view>
<view class="gameNumBox">
<text class="gameNum">{{item.gameNum}}</text>
<text>場比賽</text>
</view>
</view>
</view>
複製代碼
.wxml
中使用三目運算符判斷獲取日期與數據中的日期是否相同,從而達到高亮顯示的效果。wx.navigateBack(OBJECT)
便可返回上一頁面,如下爲文檔截圖:
值得注意的是:wx.navigateTo 和 wx.redirectTo 不容許跳轉到 tabbar 頁面,只能用 wx.switchTab 跳轉到 tabbar 頁面
因爲是第一次寫項目,相關知識儲備也還不夠,從項目開始到如今,遇到的問題可不止這些,但解決問題的過程是辛苦也是富有樂趣的。目前這個項目也還有不少部分沒有實現,但會持續更新,若是感興趣歡迎交流討論。以後將全面學習mpvue和wepy小程序框架,若使用框架寫這個項目相信會簡單一些,有機會能夠寫一個mpvue版。
個人項目在這裏哦。