世界盃來了!小程序賽事操做來一波~

前言

NBA總決賽結束還沒一週,立刻世界盃就如期而至。你們在熬夜看球,而我關在小黑屋默默碼字(可憐臉)。在體驗到小程序的方便快捷省內存以後,前段時間的「騎勇大戰」果斷用了小程序觀看。因爲體驗不錯,又正在學習小程序知識,立刻就想動手實踐學習一下「騰訊體育」小程序的製做。到目前爲止,只想說一句「選擇是好的,過程是一言難盡的」,雖然還沒所有完成,但也遇到很多問題,但願此分享能夠給你帶來幫助(源碼)。html

效果圖

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

問題及解決方案

一、scroll-view組件

讓咱們先來看看開發文檔git

  • scroll-x

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

  • scroll-y

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組件

開發文檔是好朋友,讓咱們再來看看

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.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中使用三目運算符判斷獲取日期與數據中的日期是否相同,從而達到高亮顯示的效果。
  • 返回今天。點擊「返回今天」可回退至「熱門」頁並顯示當天的賽事。使用小程序自帶 API ——wx.navigateBack(OBJECT)便可返回上一頁面,如下爲文檔截圖:
    值得注意的是:

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

結語

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

個人項目在這裏哦。

相關文章
相關標籤/搜索