微信小程序滚动Tab选项卡:左右滑动切换、触底加载分页

本文详细介绍了如何在微信小程序中实现滚动Tab选项卡,包括左右滑动切换、触底加载分页等功能。通过设置swiper组件样式和scroll组件事件,结合数据结构和赋值方法,实现了标签栏与内容的联动。同时,针对scroll组件触底事件和高度计算进行了深入探讨,提供了完整的解决方案。


效果图

在这里插入图片描述


一、顶部标签栏

定位顶部便签栏,使用color-ui的组件样式实现

<scroll-view scroll-x class="bg-white nav my-order_fixed">
      <view class="flex text-center">
            <view 
                    class="cu-item flex-sub {{index==TabCur?'text-red cur':''}}" 
                    wx:for="{{orderTypes}}" 
                    wx:key="index" 
                    bind:tap="tabSelect" 
                    data-index="{{index}}"
            >
                    {{item.title}}
            </view>
        </view>
</scroll-view>

👆在横向滑动便签栏<scroll-view>下写页面内容即可,点击事件动态切换便签栏样式,并重置底下数据内容

👆仅实现了点击便签栏刷新底部内容


二、列表内容部分

使用小程序轮播组件<swiper>实现左右滑动切换便签栏功能

重点在于轮播组件包裹下的数据内容结构以及如何赋值要考虑

<swiper 
        class="tab-box" 
        current="{{TabCur}}" 
        duration="300" 
        bind:change="switchTab"
>
        <swiper-item 
                class="tab-content" 
                wx:for="{{list}}" 
                wx:for-item="orderList" 
                wx:key="index"
         >
                <view>...</view>
         </swiper-item>
</swiper>

👆只要我们绑定了轮播组件的current="{{TabCur}}",是跟横向滑动标签栏对应的
即可实现点击便签栏触发修改Tabcur的值,自动联动轮播组件切换到相应的内容,且自带左右滑动动画效果。

swiper组件高度及上下滚动样式

轮播组件swiper必须设置其高度,可以通过class来设置css

.tab-box{
    margin-top: 100rpx;
    height: calc( 100vh - 100rpx );
}

👆要减去定位布局而脱离文档流的顶部标签栏部分高度
calc计算 calc(xx-xx)
注意:括号内运算符前后必须有空格!!!
设置轮播组件的高度后,发现内容是超出部分隐藏的,无法上下滑动显示内容

给轮播组件<swiper-item>添加样式overflow-y: scroll;,实现滚动

.tab-content{
    overflow-y: scroll;
}

三、数据结构及赋值方法

同时这里的数据结构应该是个二维数组
即:一维数组中的项,由标签栏数量决定
二维数组中的内容才是接口返回列表数据

这里标签栏数量是写死的情况,若是动态的,则需要手动创建相应多少项的空数组

data:{
    list:['','','','',''], // 全部、待付款、待配送、配送中、已完成
}

小程序setData给数组内部指定项赋值的操作如下

  • 数组某一项(已知具体下标)赋值
this.setData({
    'array[0]':'changed data'
})
  • 数组某一项(下标为变量)赋值
    'array[index]': 'xxxx',是不行的,index没有转为相应的数值
this.setData({
    [ `array[ ${index} ]` ]: 'changed data'
})
  • 对象某一项赋值
this.setData({
      'object.text': 'changed data'
})
  • 对象数组某一项对象的属性赋值
    'array[index].text': 'xxxx',是不行的,index没有转为相应的数值
const price = `array[ ${index} ].price`
this.setData({
    price: '123'
})
// 或者
this.setData({
      [ `array[ ${index} ]` ]: 'changed data'
})

👆至此标签栏点击切换底部数据内容(带动画)、左右滑动底部内容切换标签栏功能实现
其他小程序语法备忘(链接)
[目录图片]


四、scroll组件触底事件(分页相关

我们发现在轮播组件中页面的触底事件失效了,也就是我们的分页功能无法实现,这对于列表数据来说是致命的。

那只能放弃滑动内容切换标签功能了吗?不是!

既然小程序提供的页面触底事件无法触发,小程序还提供了<scroll-view>也是有触底事件的

因此,我们用<scroll-view>包裹列表数据内容
记得去除前面给<swiper-item>的滚动样式overflow-y: scroll;

<swiper 
        class="tab-box" 
        current="{{TabCur}}" 
        duration="300" 
        bind:change="switchTab"
>
        <swiper-item 
                class="tab-content" 
                wx:for="{{list}}" 
                wx:for-item="orderList" 
                wx:key="index"
         >
            
                <scroll-view
                    scroll-y
                    style="height: {{windowScrollHeight}}px;"
                    bind:scrolltolower="getMore"
                >
                        <view>...</view>
                </scroll-view>
                
         </swiper-item>
</swiper>

👆在原有的轮播组件内,加上<scroll-view>,并设置为Y向滚动。
注意,<scroll-view是放在<swiper-item>里,也就意味着,有多少个标签项就有多少个<scroll-view>

通过事件bind:scrolltolower=""来触发触底事件

于是这就导致另外一个问题,分页相关的参数,不能共用,而是相互独立

因此,分页参数也设置为一个数组(不需要是二维数组,参数不是列表数据)

data:{   
    list: [ '', '', '', '', '' ],   // 列表数据-二维数组
    totals: [0,0,0,0,0],    // 分页参数-一维数组
    isLoading: false,
    _pages: [{              // 分页参数-一维数组
      page:1,
      limit:6
    },{
      page:1,
      limit:6
    },{
      page:1,
      limit:6
    },{
      page:1,
      limit:6
    },{
      page:1,
      limit:6
    }]
}

赋值的时候要

this.setData({
        // 赋值给数组某项,判断是否拼接旧数组数据
        [`list[${TabCur}]`]: currentPageObj.page==1?res.list:[...this.data.list[TabCur],...res.list],
        
        [`totals[${TabCur}]`]: res.total,
        
        isLoading:false
})

👇通过当前标签下标Tabcur在分页数组和列表数据二维数组中判断触底事件

/**
   * 页面上拉触底事件的处理函数
   */
getMore: function () {
    const TabCur = this.data.TabCur
    
    if ( this.data.totals[TabCur]<=this.data.list[TabCur].length ) {
        return console.log('没有数据了')
    }
    
    this.data._pages[TabCur].page++
    this.init()
}

五、scroll组件的高度样式

需要注意的是<scroll-view>组件Y向滚动,需要手动设置滚动区域,才能知道触底的底部位置在哪里,一般设置为整屏高度,100vh,而传入组件参数style="height: {{windowScrollHeight}}px;"单位要px

注意这个计算屏幕高度setData不要写在多次赋值的地方
因为实际上是多个<scroll-view>组件,共用一个值,因此注意,也是在页面创建的时候获取一次即可

通过wx.getSystemInfoSync(),获取到的设备宽高是px单位的,不需要我们再去计算转换

  • app.js
onLaunch: function () {
    const res = wx.getSystemInfoSync()
    this.globalData.ww = res.windowWidth
    this.globalData.hh = res.windowHeight
}

获取整屏高度,我们在全局app.js中创建小程序时就获取到并存入全局变量了

  • 具体页面.js
const app = getApp()

/**
  * 生命周期函数--监听页面加载
  */
onLoad: function (options) {
    this.setData({
      windowScrollHeight: app.globalData.hh
    })
}
swiper组件scroll组件样式区别

👆我们可以发现设置<swiper>轮播组件的高度可以用css设置
<scroll>组件则需要设置在style里且只能是px

也就是<swiper>轮播组件设置高度可以使用vhrpx直接计算
<scroll>组件设置高度必须计算设备真实px(因为这里能直接用转换px后的设备高度,因此这里没有rpxpx的操作)

六、其他

仍然有不少细节需要补充
如切换滑动底部内容的时候,内容加载状态
这里不细说,做到的时候自然会遇到并且做个状态判断显示加载之类的逻辑即可


万事不顺,查文档
color-ui组件库github
swiper组件官方文档
scroll-view组件官方文档

如有建议和疑问可联系
QQ:1017386624
邮箱:1017386624@qq.com

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值