index.vue 2.26 KB
<template>
  <div
    v-infinite-scroll="loadMore"
    class="list-container"
  >
    <slot :list="list" />
    <div
      v-if="finishText"
      class="finish-text"
    >
      {{ finishText }}
    </div>
    <div
      v-if="listLoading"
      class="loading"
    >
      <i class="el-icon-loading" />
      加载中
    </div>
  </div>
</template>

<script>

export default {
  props: {
    loadMethod: {
      type: Function,
      default: null
    },
    total: {
      type: Number,
      default: null
    },
    totalPages: {
      type: Number,
      default: null
    }
  },
  data() {
    return {
      list: [],
      nowPage: 1,
      finish: false,
      loading: true,
      listLoading: false,
      error: false
    }
  },
  computed: {
    params() {
      return {
        pageNo: this.nowPage,
        pageSize: 10
      }
    },
    finishText() {
      if (this.error) {
        return '系统错误'
      }
      return this.finish ? (this.list.length > 0 ? '没有更多了' : '没有搜索到结果') : null
    }
  },
  methods: {
    async loadMore(loadType) {
      console.log('是否全部加载完成', this.finish, this.list)
      if (loadType === 'refresh') {
        this.nowPage = 1
        this.finish = false
        this.list = []
      }
      if (this.finish || this.listLoading) {
        return
      }
      this.listLoading = true
      try {
        const list = await this.loadMethod?.(this.params) ?? []
        this.finish = this.nowPage >= this.totalPages
        if (this.nowPage === 1) {
          this.list = list
        } else {
          this.list = this.list.concat(list)
        }
        if (!this.finish) {
          this.nowPage++
        }
        this.error = false
      } catch (e) {
        this.finish = true
        console.log(e)
        this.error = true
      } finally {
        this.listLoading = false
      }
    },
    async refresh() {
      await this.loadMore('refresh')
    }
  }
}
</script>

<style
  scoped
  lang="scss"
>
.list-container {
  height: 80vh;
  flex-grow: 1;
  padding: 0 10px 10px 10px;
  overflow-y: auto;

  .loading {
    margin: 10px 0;
    width: 100%;
    text-align: center;
  }

  .finish-text {
    width: 100%;
    text-align: center;
    color: #8a8a8a;
    line-height: calc(1em + 20px);
  }
}
</style>