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>
原文地址:https://www.cnblogs.com/wuqilang/p/15710840.html