<script setup>
import {ref, onMounted, toRef, defineProps, toRaw} from "vue"
import {unref} from "vue-demi";
const props = defineProps({
list: {
default: []
},
limitScrollNum:{
default: 5
}
})
const {list, limitScrollNum} = unref(props);
const data = toRaw(list);
const limit = toRaw(limitScrollNum);
const height = 42*limit + 'px';
let count = 0
let uu = []
let interval = null
const offset = ref(0)
const target = ref(null)
const little_Or_big = ref(null)
let testData = []
onMounted(() => {
if (data.length > limit) {
const size = target.value.clientHeight
if (data.length > 0) {
count = Math.ceil(size / 44)
data.forEach((item, index) => {
item._id = index
})
if (data.length / count > 2) {
// 数据量大
little_Or_big.value = true
testData = data.slice(0, 2 * count + 1)
if (!interval) {
interval = setInterval(load1, 1000 / 50)
}
} else if (data.length / count <= 2) {
// 数据量小
little_Or_big.value = false
testData = [...data]
if (!interval) {
interval = setInterval(load2, 1000 / 50)
}
}
}
}
})
const load1 = () => {
offset.value = offset.value - 1
if (offset.value === -count * 44) {
offset.value = 0
const temp = testData[count]._id
const yy = []
for (let i = temp; i < temp + 2 * count + 1; i++) {
if (i < data.length) {
yy.push({
...data[i]
})
} else {
yy.push({
...data[i - data.length]
})
}
}
testData = yy
}
}
const load2 = () => {
offset.value = offset.value - 1
if (offset.value === -data.length * 44) {
offset.value = 0
testData = [...data]
} else {
if (testData.length < 1.5 * data.length) {
data.forEach((item, index) => {
uu.push({
...item,
// _id: item._id + chartData.value.length
})
})
testData.push(...uu)
uu = []
}
}
}
//鼠标悬停,停止滚动
function hoverHandler() {
clearInterval(interval)
}
//鼠标离开,继续滚动
function leaveHandler() {
if (little_Or_big.value) {
interval = setInterval(load1, 1000 / 50)
} else {
interval = setInterval(load2, 1000 / 50)
}
}
</script>
<template>
<div class="scroll-container" ref="target" @mouseover="hoverHandler()" @mouseout="leaveHandler()">
<div v-if="data.length > limit"
class="scroll-list"
:style="{transform: `translate3d(0,${offset}px,0)`}">
<div
v-for="(item, index) in testData"
:key="index"
class="item"
>
<slot name="itemSlot" :item="item"></slot>
</div>
</div>
<div v-else class="scroll-list">
<div
v-for="(item, index) in data"
:key="index"
class="item"
>
<slot name="itemSlot" :item="item"></slot>
</div>
</div>
</div>
</template>
<style scoped lang="scss">
.scroll-container {
margin: 0;
padding: 0;
height: v-bind(height);
overflow: hidden;
}
</style>
使用
<template>
<default-seamless-scroll v-if="isScrollShow" :list="list" :limitScrollNum="5" v-slot:itemSlot="{item}">
<span>{{item.xxx}}</span>
</default-seamless-scroll>
</template>
<script setup>
import {ref} from "vue";
import DefaultSeamlessScroll from '@view/defaultSeamlessScroll.vue'
const isScrollShow = ref(false);
const list = [];
//模拟请求
setTimeout(() => {
for(let i=0; i < 100; i++) {
var item={index: i, column1: "xxx",column2: "xxx"};
list.push(item);
}
isScrollShow.value = true;
},3000)
</script>