世界盃來了!小程式賽事操作來一波~

與我常在就是我發表於2018-06-15

前言

NBA總決賽結束還沒一週,馬上世界盃就如期而至。大家在熬夜看球,而我關在小黑屋默默碼字(可憐臉)。在體驗到小程式的方便快捷省記憶體之後,前段時間的“騎勇大戰”果斷用了小程式觀看。由於體驗不錯,又正在學習小程式知識,馬上就想動手實踐學習一下“騰訊體育”小程式的製作。到目前為止,只想說一句“選擇是好的,過程是一言難盡的”,雖然還沒全部完成,但也遇到不少問題,希望此分享可以給你帶來幫助(原始碼)。

效果圖

(乾巴巴的開講,還不如先來波動圖)

世界盃來了!小程式賽事操作來一波~
世界盃來了!小程式賽事操作來一波~
世界盃來了!小程式賽事操作來一波~

問題及解決方案

1、scroll-view元件

讓我們先來看看開發文件

  • scroll-x

在此專案中,首頁——世界盃的頭部是一個橫向滑動的scroll-view元件,在設定了scroll-x屬性後,並未達到預期效果,scroll-view中的每個部分還是自成一行。在一番簡單搜尋後得出,設定white-space: nowrap;
樣式就可使其在同一行。

  • scroll-y

NBA賽事詳情頁中有5個sroll-view,雖然內容有點少,但還是看得出有scroll的效果的。

世界盃來了!小程式賽事操作來一波~

同樣的,在製作豎向滾動效果時,需要設定sroll-y屬性,在官方的文件中也特別說明了

使用豎向滾動時,需要給scroll-view一個固定高度,通過 WXSS 設定 height。

那麼問題來了,在scroll-view並非佔滿全屏的情況下,如何確定其高度呢?

首先想到,把包含選項卡和scroll-view的大盒子固定寬度後,在遵循文件流的情況下,將 scroll-view 高度設定為 100%不就好了嗎?但是,在如此一番設定之後,scroll-view的高度變成了大盒子的高度???(黑人問號臉),最重要的是scroll-view中的內容不能完全顯示,這就頭疼了。

隨後馬上想到可以使用彈性佈局,固定其選項卡的高度,下方的scroll-view設定flex: 1,這難道還解決不了嗎?是的,bug永相隨。下圖可以看到,選項卡的高度明顯變小,要是scroll-view的內容再多一點,選項卡就被擠到窒息了。

世界盃來了!小程式賽事操作來一波~

最後無奈只好將scroll-view的高度逐漸調整到螢幕底部的高度,簡直不要太粗暴,缺點是在不同螢幕尺寸裝置上檢視,效果不一。如果有大佬可提供較好解決方案,懇請指教。

2、swiper元件

開發文件是好朋友,讓我們再來看看

swiper元件在小程式中非常常見,它可在有限的區域展示更多內容,還能增加頁面的視覺動態效果,總之就是好。(但,好東西也是有槽點的啦)

1) 從上面動圖可看出,NBA賽事詳情頁中也使用到了swiper元件,並且與頭部的導航進行了繫結,滑動swiper可改變導航欄的狀態,點選導航欄選項可切換swiper-item。這個實現較為簡單,步驟如下:

  • data中新增一個表示下標的變數curIndex
  • 將此變數繫結到導航欄各個選項,同時使用一個三目運算子進行wx:if條件渲染,若curIndex等於當前選項的下標,則在其底部新增一個偽元素表示選中;
  • curIndex繫結到swipercurrent屬性中,通過選項卡的bindtap事件和swiperbindchange事件實時切換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.jsbindswiper(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]
})
}複製程式碼

如果大佬們有解決方案歡迎交流討論。詳細程式碼檢視可點選這裡

3、選項卡

天啦嚕!你連選項卡都要說?(笑哭)聽我解釋。

通常我們使用的選項卡中的選項都是 2 到 4 個,如果不嫌麻煩,我們只要將選項卡和其對應的內容逐個在.wxml中寫出來就好了。但是,一旦選項變多,若逐個寫出,那.wxml中的程式碼將跟“懶婆娘的裹腳布”似的。此時,使用wx:for來迴圈輸出選項就非常有必要了。另外,如果每個選項中的內容都是類似的就更好了,可通過選項卡的點選事件獲得當前選項的id,根據id使用wx:if條件渲染來決定當前選項卡顯示的資料。在這又要cue一下我們的NBA賽事詳情頁,此頁面中的球員榜這個swiper-item就包含了一個有 5 個選項的選項卡。

詳細程式碼檢視可點選這裡

4、自定義日曆

為了更好的體驗,體育賽事總要加入日曆,方便使用者檢視賽事安排。若使用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中使用三目運算子判斷獲取日期與資料中的日期是否相同,從而達到高亮顯示的效果。
  • 返回今天。點選“返回今天”可回退至“熱門”頁並顯示當天的賽事。使用小程式自帶 API ——wx.navigateBack(OBJECT)即可返回上一頁面,以下為文件截圖:
    世界盃來了!小程式賽事操作來一波~

    值得注意的是:

wx.navigateTo 和 wx.redirectTo 不允許跳轉到 tabbar 頁面,只能用 wx.switchTab 跳轉到 tabbar 頁面

結語

由於是第一次寫專案,相關知識儲備也還不夠,從專案開始到現在,遇到的問題可不止這些,但解決問題的過程是辛苦也是富有樂趣的。目前這個專案也還有很多部分沒有實現,但會持續更新,如果感興趣歡迎交流討論。之後將全面學習mpvue和wepy小程式框架,若使用框架寫這個專案相信會簡單一些,有機會可以寫一個mpvue版。

我的專案在這裡哦。

來源:https://juejin.im/post/5b22f71fe51d4558ab7b16d4

相關文章