uniapp-微信小程序实现swiper左右滚动切换tab,上下滚动加载列表

这篇具有很好参考价值的文章主要介绍了uniapp-微信小程序实现swiper左右滚动切换tab,上下滚动加载列表。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

思路:左右滑动使用swiper,上下滑动用scroll-view,swiper改变时同时改变tab并更新列表

坑点:

1. swiper高度问题,导致滑动不到最底部和最顶部

        需要手动计算,减去顶部高度和底部tabbar,并且需要同时设置padding-top和paddin-botton,否则列表显示不完整

2. 由于最开始的代码是每次切换tab后都会重新请求,导致swiper还没切换成功的过程中,显示的列表错误

        将代码改造成每一个tab下面的list都是隔离开的,原先使用了一个list维护不同tab

3. 每个tab下的list的加载完成状态也需要隔离开,否则导致tab1切换到tab2以后,tab2将控制加载完成的状态改为true后,返回tab1无法加载第2页了

4. 触底加载

        无法使用系统的触底加载了,需要使用scroll-view的自定义上拉刷新方法

5. 下拉更新

        也需要自定义,由于目前我的系统自带的还是正常的,所以还没有改造,但是体验没有scroll-view的好,因为顶部tab会遮挡下拉刷新的loading状态,后期再改造

源码:已去除不相关代码文章来源地址https://www.toymoban.com/news/detail-761976.html

<template>
  <view class="home-page">
    <my-tabs :tabs="tabs" :currentTab="currentTabIndex" @change="onTabChange" :top="topStyle.total" isFixed>
    </my-tabs>
    <swiper class="activity-swiper" :current="currentTabIndex" interval="500" @change="onSwiperChange"
      :style="{ height: `calc(100vh - ${listStyle.paddingTop} - ${listStyle.paddingBottom})`, paddingBottom: listStyle.paddingBottom, paddingTop: listStyle.paddingTop,}">
      <swiper-item class="activity-swiper-item" v-for="item in tabs" :key="item.key" :item-id="item.key"
        :style="{ paddingBottom: 0, paddingTop: 0 }">
        <scroll-view scroll-y class="scroll-list" @scrolltolower="onBottom" :style="{ height: '100%' }"
          :scroll-top="scrollTop" @scroll="scroll">
          <card-activity v-for="(activity, index) in listData[item.index]" :key="activity.activityId" :data="activity"
            custom-class="activity-item" @click="toActivityDetail" @share="onShare"></card-activity>
          <tui-nomore v-if="isListFinished[item.index] && listData[item.index].length > 3"></tui-nomore>
        </scroll-view>
      </swiper-item>
    </swiper>
  </view>
</template>

<script>
  import {
    mapState
  } from 'vuex'
  import {
    userApi,
    activityApi
  } from '@/api'
  import {
    defaultConst,
    shareTypeConst,
  } from '@/const'
  const tabObj = {
    textList: [{
        name: '我创建的',
        key: 'create',
        index: 0
      },
      {
        name: '我参与的',
        key: 'partake',
        index: 1
      },
      {
        name: '我关注的',
        key: 'follow',
        index: 2
      }
    ],
    value: {
      0: 1,
      1: 2,
      2: 3,
    }
  }
  export default {
    data() {
      return {
        currentActivity: {},
        tabs: tabObj.textList,
        currentTabIndex: 0,
        currentTabValue: 1,
        listData: {
          0: [], // create
          1: [], // partake
          2: [], // follow
        },
        // 每个tab的加载状态隔离开:解决切换到第三个tab加载完成后,返回第一个tab无法加载第二页的问题
        isListFinished: [false, false, false],
        pageIndex: 1,
        isListLoading: false,

        tabbarIndex: 0,

        scrollTop: 0,
        oldScrollTop: 0
      }
    },
    computed: {
      ...mapState(['systemInfo', 'userInfo', 'showTabBarDot']),
      topStyle() {
        const {
          statusBarHeight
        } = this.systemInfo
        const menuButtonInfo = wx.getMenuButtonBoundingClientRect()
        const navigationBarHeight = (menuButtonInfo.top - statusBarHeight) * 2 + menuButtonInfo.height
        return {
          statusBarHeight,
          navigationBarHeight,
          total: statusBarHeight + navigationBarHeight
        }
      },
      listStyle() {
        return {
          paddingTop: this.topStyle.total + 45 + 'px',
          paddingBottom: '180rpx',
        }
      }
    },
    watch: {
      currentTabIndex(value) {
        // 首次切换tab才会重新加载数据
        if (!this.listData[value].length) this.getActivityList(true)
        // this.isListFinished = false
      },
    },
    methods: {
      async getActivityList(isRefresh, params, isFirst) {
        const tab = this.currentTabIndex
        this.showNoData = false

        if (isRefresh) {
          this.pageIndex = defaultConst.DEFAULT_PAGE_INDEX
          this.isListFinished[this.currentTabIndex] = false
          this.listData[this.currentTabIndex] = []
        }
        const data = {
          pageIndex: this.pageIndex++,
          pageSize: defaultConst.DEFAULT_PAGE_SIZE,
          type: this.currentTabValue,
        }
        Object.keys(params || {}).map(key => {
          if (params[key]) {
            data[key] = params[key]
          }
        })
        const {
          hasNext,
          list
        } = await activityApi.getList(data)
        if (tab !== this.currentTabIndex) return

        if (!hasNext) {
          this.isListFinished[this.currentTabIndex] = true
        }
        if (isRefresh) {
          uni.stopPullDownRefresh()
        }
        this.listData[this.currentTabIndex].push(...list)

      },
      onTabChange({
        index
      }) {
        this.currentTabIndex = index
        this.currentTabValue = tabObj.value[index]
        if (!this.listData[index].length) this.skeletonShow = true
        this.goTop()
      },
      onSwiperChange(e) {
        this.currentTabIndex = e.detail.current
        this.currentTabValue = tabObj.value[e.detail.current]
        if (!this.listData[e.detail.current].length) this.skeletonShow = true
        this.goTop()
      },
      onNoticeClose() {
        this.showNotice = false;
      },
      toActivityDetail(id) {
        uni.navigateTo({
          url: `/pages/activity/detail?activityId=${id}`
        })
      },
      async onShare(activity) {
        const res = await activityApi.getDetail({
          activityId: activity.activityId
        })
        this.currentActivity = res
        this.$refs.shareActivity.share()
      },
      toCreate() {
        uni.navigateTo({
          url: '/pages/activity/create'
        })
      },
      onBottom() {
        console.log('触底了')
        if (!this.isListFinished[this.currentTabIndex]) {
          this.getActivityList(false)
        }
      },
      scroll(e) {
        //记录scroll  位置
        this.oldScrollTop = e.detail.scrollTop
      },
      goTop(e) {
        //视图会发生重新渲染 scrollTop不会随着滚动而实时更新 所以需要手动设置 之所以不在scroll方法中设置是为了防止页面抖动
        this.scrollTop = this.oldScrollTop
        //当视图渲染结束 重新设置为0
        wx.nextTick(() => {
          this.scrollTop = 0
        });
      }
    },
 
    onLoad() {
      this.skeletonShow = true
      this.getActivityList(false)
    },

    onPullDownRefresh() {
      this.skeletonShow = true
      this.getActivityList(true)
    },
  }
</script>

<style lang="scss" scoped>
  .activity-swiper {

    &-item {
      box-sizing: border-box;
      padding-left: 20rpx;
      padding-right: 20rpx;
    }

    /deep/ .activity-item {
      margin-top: 20rpx;
    }
  }

  .text-link {
    color: $text-link;
  }

  .list-no-data-text {
    color: $text-3;
  }
</style>

到了这里,关于uniapp-微信小程序实现swiper左右滚动切换tab,上下滚动加载列表的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 改造微信小程序Swiper组件,自定义切换动画

    index.tsx index.less conts.ts 改造Swiper组件,符合业务的设计和动画效果

    2024年04月15日
    浏览(46)
  • 微信小程序中 使用swiper 滑动切换一级、二级导航

    其中遇到一个大问题使我放弃了swiper的使用,swiper有一个固定高度不太好处理,最终使用了touch事件去处理触摸移动,之后会再写一篇文章记录,处理不复杂的话还是可以用swiper的 效果根据手指滑动切换二级导航、二级切换完成切换一级导航   其中遇到一个大问题使我放弃了

    2024年02月17日
    浏览(48)
  • 微信小程序(原生)——轮播图swiper、1秒切换、自动轮播、无缝切换

    微信小程序的轮播图制作,且图片不变形。1秒切换、自动轮播、无缝切换 index.wxml文件: index.wxss文件: 完整示意图 swiper网址:https://developers.weixin.qq.com/miniprogram/dev/component/swiper.html image网址:https://developers.weixin.qq.com/miniprogram/dev/component/image.html 图片处理方面: mode=\\\"aspectFi

    2024年02月15日
    浏览(54)
  • 微信小程序———同一页面内左右滑动切换内容显示

    一、微信小程序事件  由于首先介绍一下微信小程序中的事件,可选择快速略过或者直接进去之后的重点内容 一、什么是事件 事件是视图层到逻辑层的通讯方式。 事件可以将用户的行为反馈到逻辑层进行处理。 事件可以绑定在组件上,当达到触发事件,就会执行逻辑层中对

    2024年02月03日
    浏览(68)
  • 微信小程序 table表格 固定表头和首列 右侧表格可以左右滚动

    1.左侧一列固定不动 2.右侧表格内容可以左右滚动 3.单元格内容平均分配 4.每一行行高可以由内容撑开 通过 js 设置左侧一列行高与右侧表格内容行高保持一致   如果不想要左侧固定,整个table 表格都可以滚动的 那么可以修改结构和样式 比如把左侧固定的代码注释掉,在

    2024年02月08日
    浏览(52)
  • 微信小程序实现左右滑动触发内容及联动选项卡切换、Math、abs、findIndex、parseInt、String、push、createSelectorQuery、selectAll

    在写原生微信小程序项目的时候,遇到左右滑动更新内容及联动选项卡切换的功能。于是就写了这篇文章,关于文章的 css 不在此文章中展示,使用了公共的自定义类名,所以通过类名大概就能推敲出 css 的属性及值。 页面分为三个模块,分别是顶部横向滚动选项卡,底部内

    2024年02月09日
    浏览(70)
  • uniapp写微信小程序使用swiper修改指示点

    原来的指示点样式 在App.vue的style直接加入: wx-swiper .wx-swiper-dot {         width: 30rpx;         height: 6rpx;         border-radius: 20%;     }      wx-swiper .wx-swiper-dot-active {         background-color: #000;         width: 30rpx;     } 改变后的

    2024年04月27日
    浏览(40)
  • 微信小程序 uniapp 电商项目使用scroll-view实现左右菜单联动,点击菜单子分类联动对应商品

    最近写了个微信小程序项目,一开始不理解scroll-view用法,用的另外一种方法写的,虽然实现了效果,但是代码层面来说,不大合理,后来又通过努力,用scroll-view实现了效果。现写个文章做个记录,方便自己和大家学习记录。 效果图请看第一张。布局:左右布局,右边又分

    2024年02月14日
    浏览(75)
  • 微信小程序 table表格 固定表头和首列 右侧表格可以左右滚动(多种表格演练)

    最近在做公司的项目需要到表格展示数据,但是微信小程序是没有原生table标签的,于是就百度各种搜...发现结构有类似的就粘过来修改,要善于学习和借鉴别人的经验使其变成为自己的东西,学无止境~ 在这里做下记录! 1.左侧一列固定不动 2.右侧表格内容可以左右滚动 3

    2024年02月09日
    浏览(112)
  • 微信小程序在ios端上下左右滑动以及底部滚动条的解决方案

    最近在写小程序,碰到一个非常棘手的问题,就是安卓没事,苹果手机上的页面能上下左右的滑动,不美观这里我理解为不兼容,本着有问题就去解决,苹果默认应该是滑动的,下面是解决方法 底部滚动条解决

    2024年02月04日
    浏览(132)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包