列表组建封装
<template>
<van-pull-refresh
ref="ListRefreshRef"
v-model="data.freshData.refreshLoad"
:class="classMap?.refreshClass"
disabled
@scroll="scrollHander"
@refresh="onRefresh"
>
<van-list
v-model:loading="data.freshData.listLoading"
:finished="data?.freshData?.listFinished"
:immediate-check="false"
:finished-text="finishedText"
:offset="20"
class="h-[100%] scroll-container pt-[10px] px-[12px]"
@load="onLoad"
>
<slot />
</van-list>
</van-pull-refresh>
</template>
<script setup name="ListRefresh">
const emit = defineEmits(['onRefresh', 'onLoad'])
const props = defineProps({
freshMap: {
type: Object,
default: () => {
return {
refreshLoad: false,
listLoading: false,
listFinished: false,
listData: []
}
}
},
classMap: {
type: Object,
default: () => {
return {
refreshClass: ''
}
}
},
resetScroll: {
type: Number,
default: 0
},
finishedText: {
type: String,
default: '没有更多了'
},
emptyText: {
type: String,
default: '暂无数据'
}
})
const data = reactive({
freshData: props?.freshMap
})
// 判断数据是否为空
const isEmpty = computed(() => {
const { listFinished, listData } = data?.freshData ?? {}
return listFinished && !listData?.length
})
const ListRefreshRef = ref()
// 下拉刷新
const onRefresh = () => {
emit('onRefresh')
}
// 触底加载
const onLoad = () => {
emit('onLoad')
}
// 重置滚动距离
const onResetScroll = () => {
ListRefreshRef.value.$el.scrollTop = 0
}
// 滚动监听
const scrollHander = () => {}
watchEffect(() => {
if (props?.resetScroll) {
onResetScroll()
}
})
</script>
<style lang="less" scoped></style>
hooks封装useListRefresh.ts方法
import { ref } from 'vue'
type PromiseFunc = (params?: any) => Promise<any>
interface IPage {
pageIndex: number
pageSize: number
}
export const useListRefresh = <T>(): {
pagination: IPage
listData: T[]
loading: boolean
finished: boolean
refreshing: boolean
getListData: (func: PromiseFunc) => Promise<any>
refreshCallback: (func: PromiseFunc) => void
loadMore: (func: PromiseFunc) => void
} => {
const pagination = ref<IPage>({
pageIndex: 1,
pageSize: 10
})
const listData = ref([])
const loading = ref(false)
const finished = ref(false)
const refreshing = ref(false)
const getListData = async (func: PromiseFunc) => {
loading.value = true
const { data, pages } = await func()
if (refreshing.value) {
refreshing.value = false
listData.value = []
}
const list = data ?? []
listData.value =
pagination.value.pageIndex > 1 ? listData.value.concat(list) : list
loading.value = false
finished.value = listData.value.length >= pages?.total ?? 0
}
const refreshCallback = (func: PromiseFunc) => {
finished.value = false
loading.value = true
pagination.value.pageIndex = 1
setTimeout(() => {
getListData(func)
}, 20)
}
const loadMore = async (func: PromiseFunc) => {
pagination.value.pageIndex += 1
getListData(func)
}
return {
pagination,
listData,
loading,
finished,
refreshing,
getListData,
refreshCallback,
loadMore
}
}
export default useListRefresh
组件中使用
const {
pagination,
listData,
loading,
finished,
refreshing,
getListData,
refreshCallback,
loadMore
} = useListRefresh();