uniapp swiper长列表优化,纵享丝滑

2024-04-11 21:10:55

类似抖音作品列表,按照普通的列表渲染一直累加数据,作品数量加载到一定量会出现卡顿,通过固定数量的swiper item来处理 如下:

<template lang="pug">
div.container
  swiper.work_list(
    v-if="isInit"
    :vertical="true"
    :circular="circular"
    :skip-hidden-item-layout="true"
    easing-function="default"
    @change="swiperChange"
  )
    swiper-item(v-for="(item, index) in showList" wx:key="id")
      div.content {{item.name}}
</template>

<script lang="ts" setup>

import {ref} from "vue"
import {onLoad} from "@dcloudio/uni-app";


interface work {
  id: number,
  name: string,
  extra_id: number
}

const workList = ref<work[]>([])
const showList = ref<work[]>([])
// 当前展示的作品索引
const workIndex = ref(0)
// 当前展示的swiper-item索引
const showIndex = ref(0)

const id = ref(0)
// 当展示workList的第一个或最后一个变为false
const circular = ref(false)

onLoad((options: ptAny) => {
  init()
})

const init = ():void => {
  id.value = id.value + 1
  let work = {
    name: "id name " + id.value,
    id: id.value,
    extra_id:  id.value + 1,
  }
  workList.value.push(work);
  showList.value.push(work);
  if (work.extra_id > 0 && showList.value.length < 3){
    // 模拟初始化保证最少有三个作品
    return init()
  }
}

const swiperChange = (e: ptAny): void => {
  if (showList.value.length < 3){
    return;
  }
  // 当前展示的swiper-item索引 0 1 2
  const current = e.detail.current
  // 向后滑(从下向上滑动):2、-1, 向前滑:-2、1
  const direction = showIndex.value - current
  showIndex.value = current

  if (direction == 2 || direction == -1) {
    let temp = workIndex.value + 1
    workIndex.value = temp == workList.value.length ? 0 : temp;
  } else  {
    workIndex.value = workIndex.value - 1 == -1 ? workList.value.length - 1 : workIndex.value - 1;
  }

  let temp = workList.value.length - 1
  if ((direction == 2 || direction == -1) && temp - workIndex.value < 1 && workList.value[temp].extra_id > 0) {
    // 模拟加载更多
    id.value = id.value + 1
    workList.value.push({
      name: "id name " + id.value,
      id: id.value,
      extra_id: id.value < 8 ? id.value + 1 : 0,
    });
  }

  let changeIndex, changeWorkIndex
  if (direction == 2 || direction == -1) {
    changeIndex = showIndex.value + 1 == 3 ? 0 : showIndex.value + 1
    changeWorkIndex = workIndex.value + 1 == workList.value.length ? 0 : workIndex.value + 1
  }else{
    changeIndex = showIndex.value - 1 == -1 ? 2 : showIndex.value - 1
    changeWorkIndex = workIndex.value - 1 == -1 ? workList.value.length - 1 : workIndex.value - 1
  }
  if (showIndex.value === 0 && workIndex.value === 0 && workList.value[temp].extra_id > 0){
    // 第一个作品 且还有更多作品
    setTimeout(()=>{
      circular.value = false
    }, 500)
  }else {
    setTimeout(()=>{
      circular.value = true
    }, 500)
  }
  showList.value[changeIndex] = workList.value[changeWorkIndex]
}

</script>
<style lang="scss" scoped>
.container{
  width: 100vw;
  height: 100vh;
  background-color: #fafafa;
  padding: 20rpx;
  box-sizing: border-box;
  .work_list, .content{
    width: 100%;
    height: 100%;
  }
}
</style>
本文由"putyy"原创,转载无需和我联系,但请注明来自putyy
您的浏览器不支持canvas标签,请您更换浏览器