类似抖音作品列表,按照普通的列表渲染一直累加数据,作品数量加载到一定量会出现卡顿,通过固定数量的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>