首頁 >web前端 >js教程 >淺談小程式如何實現tab卡片切換功能

淺談小程式如何實現tab卡片切換功能

青灯夜游
青灯夜游轉載
2021-12-15 10:24:183157瀏覽

小程式如何實作tab卡片切換功能?這篇文章跟大家介紹微信小程式實作tab卡片切換的方法,希望對大家有幫助!

淺談小程式如何實現tab卡片切換功能

一、UI與互動

#首先我們來看看要實現的ui模樣和互動效果吧,下圖是我們的一個入口,以下的每個icon區域點擊進去都會展示對應的卡片展示。

淺談小程式如何實現tab卡片切換功能

例如我點選tab2這一個icon時,對應跳到如下圖。

該頁面的展示為頭部是一長條tab欄,左右可滑動,兩邊需要留出空白區域以實現兩端的tab可實現居中效果,點擊對應的tab可展示對應的卡片,且該tab的文字會居中展示。類似輪播圖左右切換的效果,我想身為使用者應該很容易可以想到這種互動。

目前啟動的卡片會有一個感覺比別的卡片稍微大那麼一點點的效果,且可看見前後的卡片的邊。且該卡片區域也可左右滑動實現與頭部tab欄一樣互動的效果。

大概就是這樣的一個互動效果啦!

淺談小程式如何實現tab卡片切換功能

二、實作方案的設計

1、首先我們需要知道前端展示的所有tab是一直這樣展示這麼多個嗎,還是說有可能後續會擴展,再或許說有可能在這上面進行迭代。我個人認為這裡可以跟後端商量一下,將我們需要展示的內容統一做成一套常數配置,然後就可以做出我們的動態渲染了。在這裡我是大概維護了這樣的一個constant。

data: [
  {
    title: 'tab2', // 标题
    logoUrl: 'xxx', // 图标地址
    isNeed: false, // 是否需要该tab 
    id: '', // 每个tab对应的一个id,与后端交互使用
    content: '' // 每个tab对应的一些内容,用于扩展
    ...
  }
]

就是大概的這樣以上的一個資料結構。

2、在入口處點擊對應icon時可以把相對應的數組indexid帶入詳情頁面,以實現對應的卡片展示以及對應的ui

3、在詳情頁面的設計中,我將該頁面分成兩個元件展示。

  • Header為對應的scroll-tab元件,在該元件中我使用了微信小程式提供的元件scroll-view,在這裡我們需要給其設定scroll-x的參數使其能夠進行左右滑動,設定scroll-left參數實作我們點擊某個tab或滑動卡片時能夠捲動到中間去。
  • Content為對應的swiper-card元件,在該元件中我使用了微信小程式提供的元件swiper,在這裡我們需要給其設定previous-marginnext-margin屬性設定目前卡片與前後兩張卡片的距離,current屬性設定目前展示的卡片,bindchange事件用於卡片切換時的交互。
  • index頁面傳參我選擇傳送對應的一些資料以及current值事件處理函數
<view>
    <scroll-tab data="{{data}}" current="{{current}}" bind:chooseDetail="handleChooseDetail" />
    <swiper-card data="{{data}}" current="{{current}}" bind:swiperChange="handleSwiperChange" />
</view>

4、具體實現

  • 对于Header的tab栏两边留出可滑动的空间,因为scroll-view内部元素是无法占满该tab的宽度的,因此我们没有办法给其设置100%来实现。在这里我开始的想法是给其前后放置一个空白元素来给其宽度实现,后面参考了某个写法用了page-meta这个我也不太清楚是什么鬼的组件来设置左右的padding来实现,但是会有page-meta只用于页面首个节点的warning。对于两边距离的的设置,和scroll-left的设置,我采用了以下方法。
wx.getSystemInfo({
          success: res => {
            this.marginWidth = res.windowWidth / 2 // 两边空白距离
          }
        })
        
        
const computedPosition = (margin, textArr, preWidthArr) => {
  // margin每个tab之间的间距
  // textArr为所有tab的文字宽度的数组
  // preWidthArr为每一个tab与前一个tab的距离数组,第一个默认为0
  let distanceArr = []
  let len = textArr?.length
  for (let i = 0; i < textArr?.length; i++) {
    distanceArr.unshift(preWidthArr[len - 1] + (len - 1) * margin + textArr[len - 1] / 2)
    len--
  }
  // distanceArr为每个tab居中展示时应该设置的scroll-left值
  return distanceArr
}

// textArr[n] = 第 n - 1元素的宽度
// const widthArr = [78, 78, 78, 52, 52, 52]

// preWidthArr[n] = 第n - 1个tab距离前面tab的距离 = 元素宽 + margin
// 第一个tab没有前面的元素
// const arr = [0, 78, 156, 234, 286, 338]

// 获取元素信息
getElementAttr() {
        wx.createSelectorQuery()
          .in(this)
          .selectAll(&#39;.swiper-text__item&#39;)
          .boundingClientRect(res => {
            const textWidth = res?.map(item => item.width)
            const preWidth = this.getPreWidth(textWidth)
            this.distanceArr = computedPosition(MARGIN, textWidth, preWidth)
          })
          .exec()
},
getPreWidth(textWidth) {
        const arr = [0]
        for (let i = 0; i < textWidth.length - 1; i++) {
          arr.push(textWidth[i] + arr[i])
        }
        return arr
}
  • 对于Content内容区域的卡片,可以给当前卡片与别的卡片设置不同的transfrom: scale(倍数),并且给一个过渡效果transition即可实现简单的交互效果。

三、大功告成,开始复盘

  • scroll-view的scroll-left曾经踩过不生效的
  • scroll-view的内容区域并不能撑满宽度100%
  • 如何根据不同tab文字的宽度来设置对应的scroll-left距离
  • 如何实现左右两边留出可滑动区域
  • 如何做出更顺畅更友好的交互效果

写在最后

前段时间接了这个需求的时候我作为owner,和一个同事为该需求评估排期时间时评的是10人日,我自然而然的也想尝试一下所以选择了ui与交互更为复杂的内容,当然以上要实现的内容只是其中一个部分,说实话在实现过程中我真的挺痛苦的,还有一个半圆弧状的进度条展示,首尾都要有弧度的那一种,作为一个应届小白,还是有太多不会的东西了,即使是这些在他们眼里看作为很简单的内容,一下就能实现的内容,在我这里可要经历太多了,我知道我菜,但我会继续努力,作为一个前端开发,高还原度实现ui设计稿一直作为我的初衷。但希望你们不要以这个我xxx(多久时间)就能做出来的口吻来pua我,至少我认为在几年后我会比你们更加优秀,但一定不会用这样的口吻来对待我的应届同事们。

【相关学习推荐:小程序开发教程

以上是淺談小程式如何實現tab卡片切換功能的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:juejin.cn。如有侵權,請聯絡admin@php.cn刪除