vue基于vant封装上拉加载/下拉刷新组件ListScroller
components/ListScroller.vue
<template> <van-pull-refresh ref="vanPullRefreshRef" v-model="refreshing" @refresh="onRefresh" :style="{height: listHeight}"> <van-list v-model="loading" @load="onLoad" offset='300'> <slot></slot> </van-list> </van-pull-refresh> </template> <script> export default { name: 'ListScroller', props: { height: { type: String | Number, default: '' } }, watch: { height: { handler(val) { this.setListHeight(Math.abs(val)) }, immediate: true } }, data() { return { loading: false, // 加载更多 refreshing: false, // 重新加载 listHeight: '' // 容器高度 可传 66 -66 '66' '-66' 全屏高度则不传 } }, methods: { setListHeight(height) { const h = height ? document.documentElement.clientHeight - height + 'px' : '100%' this.listHeight = h }, onRefresh() { this.$emit('on-pulldown-loading', () => { this.refreshing = false // 下拉刷新成功后关闭顶部刷新状态 }) }, onLoad() { this.$emit('on-pullup-loading', () => { this.loading = false // 上拉加载成功后关闭底部加载状态 }) } } } </script> <style lang="less" scoped> .van-pull-refresh { overflow-y: auto; -webkit-overflow-scrolling: touch; } </style>
使用:
1、引入&注册:
import ListScroller from '@/components/ListScroller'
components: { ListScroller }
2、data&methods
data() { return { queryParams: { page: 1, pageSize: 10 }, totalRecords: '', feedbackList: [] } }
async getFeedbackList() { this.$toast.loading({message: '加载中...', forbidClick: true, duration: 5}) const { success, data, totalRecords } = await getFeedbackListApi(this.queryParams) if (success) { this.totalRecords = totalRecords if (this.queryParams.page === 1) {this.feedbackList = data } else { this.feedbackList.push(...data) } this.$toast.clear() } }, // 刷新 refrash(cb) { this.queryParams.page = 1 this.getFeedbackList().then(_ => { cb && cb() }) }, // 加载更多 loadMore(cb) { const { feedbackList, totalRecords } = this if (totalRecords > feedbackList.length) { this.queryParams.page++ this.getFeedbackList().then(_ => { cb && cb() // 也可以通过ref设置子组件中状态值 this.$refs.listScrollerRef.loading = false }) } else { cb && cb() } }
3、DOM:
<ListScroller height='-66' @on-pulldown-loading="refrash" @on-pullup-loading="loadMore"> <div class="scroller-container" v-if="feedbackList.length > 0"> <van-swipe-cell left-width='0' v-for="item in feedbackList" :key="item.id"> <div class="feedback-card" @click="handleDetails(item.id)"> <p>{{item.title}}</p> <p>{{item.projectName}}</p> <p v-if="item.area">{{item.area}}</p> <div> <p><van-icon name="location" /><span>{{item.visitPlanTitle}}</span></p> <p>{{item.visitTime}}</p> </div> </div> <template #right> <van-button text="编辑" @click="handleEdit(item)" /> <van-button text="删除" @click="handleDelete(item.id)" /> </template> </van-swipe-cell> </div> <div v-else class="empty-data">暂无数据</div> </ListScroller>