vue3+vant 移动端列表渲染
<template>
<div>
<van-pull-refresh v-model="refreshing" @refresh="onRefresh">
<van-list v-model:loading="loading" :finished="finished" @load="onLoad">
<template v-for="(item, index) in list" :key="item.id">
<slot :item="item" :index="item.id" :list="list" :idx="index"></slot>
</template>
<template #finished>
<no-data
:title="list.length ? '没有更多了~' : '暂无内容'"
:showImg="!list.length"
></no-data>
</template>
</van-list>
</van-pull-refresh>
</div>
</template>
<script setup>
import { ref } from 'vue';
import noData from '@/components/NoData.vue';
const props = defineProps({
isPage: {
type: Boolean,
default: true
},
getListData: {
type: Function,
default: () => {}
},
otherParams: {
type: Object,
default: () => {}
},
pageSize: {
type: Number,
default: 20
},
isIndex: {
type: Boolean,
default: false
}
});
const refreshing = ref(false);
const list = ref([]);
const loading = ref(false);
const finished = ref(false);
const pageNum = ref(1);
const currentPage = ref(0);
const handlePromiseData = promiseData => {
return promiseData
.then(res => {
if (!props.isPage) {
list.value = res.data;
finished.value = true;
refreshing.value = false;
return res;
} else {
const { total, records } = res.data;
if (refreshing.value) refreshing.value = false;
list.value = [...list.value, ...records];
if (
total <=
(props.isIndex ? res.data.size : pageNum.value * props.pageSize)
) {
finished.value = true;
} else {
pageNum.value++;
}
return res;
}
})
.catch(() => {
loading.value = false;
finished.value = true;
});
};
const onLoad = async () => {
if (currentPage.value === pageNum.value) return;
currentPage.value = pageNum.value;
loading.value = true;
const promiseData = props.getListData({
pageSize: props.pageSize,
pageNumber: pageNum.value,
...props.otherParams
});
await handlePromiseData(promiseData);
loading.value = false;
};
const onRefresh = () => {
currentPage.value = 0;
list.value = [];
finished.value = false;
pageNum.value = 1;
setTimeout(() => onLoad(), 100);
};
defineExpose({ onRefresh, otherParams: props.otherParams });
</script>