vue-element(四) el-table滚动加载

说明

自用

一、自定义指令实现

参考:

vue element-ui table表格滚动加载

    1. template

    1. script
export default {
  name: 'WbTable',
  // 自定义指令
  //  vue 官方文档:https://cn.vuejs.org/v2/guide/custom-directive.html
  directives: {
    loadmore: {
      bind (el, binding) {
        const selectWrap = el.querySelector('.el-table__body-wrapper')
        selectWrap.addEventListener('scroll', function () {
          let sign = 100
          const scrollDistance = this.scrollHeight - this.scrollTop - this.clientHeight
          if (scrollDistance <= sign) {
            binding.value()
          }
        })
      }
    }
  },
  props: {
    // 服务端列表数据接口名称
    url: {
      type: String,
      required: true
    },
    // 服务端列表数据接口请求参数
    params: {
      type: Object,
      required: true
    }
  },
  data () {
    return {
      tableData: [],
      loading: false,
      total: 0
    }
  },
  created () {
    this.limit = this.params.limit ? this.params.limit : 8
    this.offset = this.params.offset ? this.params.offset : 0
    // 根据单元格最小高度计算表格高度
    this.height = this.limit * 45
    this.append(this.params)
  },
  methods: {
    append (params) {
      this.loading = true
      this.$http[this.url]({
        ...params,
        offset: this.offset,
        limit: this.limit
      })
        .then(result => {
          this.tableData = [
            ...this.tableData,
            ...result.data.rows
          ]
          console.log(this.tableData)
          this.total = result.data.total || 0
        })
        .finally(() => {
          this.loading = false
        })
    },
    reload () {
      // 刷新重置 offset 和表格
      this.params.offset = 0
      this.tableData = []

      // api动态加载完 开始重新请求数据
      this.$nextTick(() => {
        this.init(this.params)
      })
    },
    // 滚动事件
    loadMore () {
      const newOffset = this.offset + this.limit
      if (newOffset < this.total && !this.loading) {
        this.offset = newOffset
        this.append(this.params)
      }
    }
  }
}
  • 3.效果


二、与el-infinite-scroll 结合

有大佬已经实现了,查看:

element-ui 的 el-table 上使用无限滚动加载(与自带的 infinite-scroll 结合):https://blog.csdn.net/baidu_27769027/article/details/101924676
GitHub代码:https://github.com/yujinpan/el-table-infinite-scroll/blob/master/src/directives/table-infinite-scroll.js

三、 使用vue-infinite-loading实现滚动加载

参考:

官方文档(中文):https://peachscript.github.io/vue-infinite-loading/zh/
vue elmentui table 滚动加载:https://www.jianshu.com/p/48df3fd85dd6

1. 安装

注意:vue-infinite-loading2.0只能在Vue.js2.0中使用。如果你想在Vue.js1.0中使用,请安装vue-infinite-loading1.3版本

npm install vue-infinite-loading --save
2.引入
import InfiniteLoading from 'vue-infinite-loading'
export default {
  name: 'WbTable',
  components: {InfiniteLoading}
}
3.完整使用
  • template

  • script
import InfiniteLoading from 'vue-infinite-loading'
export default {
  name: 'WbTable',
  components: {InfiniteLoading},
  props: {
    // 服务端列表数据接口名称
    url: {
      type: String,
      required: true
    },
    // 服务端列表数据接口请求参数
    params: {
      type: Object,
      required: true
    }
  },
  data () {
    return {
      tableData: [],
      loading: false,
      total: 0,
      isOver: false,
      infiniteId: new Date()
    }
  },
  created () {
    this.limit = this.params.limit ? this.params.limit : 8
    this.offset = this.params.offset ? this.params.offset : 0
    // 根据单元格最小高度计算表格高度
    this.height = this.limit * 45
  },
  methods: {
    // 滚动事件
    async loadMore ($state) {
      this.loading = true
      if (!this.isOver) {
        await this.$http[this.url]({
          ...this.params,
          offset: this.offset,
          limit: this.limit
        })
          .then((result) => {
            this.tableData = [
              ...this.tableData,
              ...result.data.rows
            ]
            this.total = result.data.total || 0
            if (this.total <= this.tableData.length) {
              this.isOver = true
              $state.complete() // 全部加载完成
            } else {
              $state.loaded() // 单个数据加载完毕
              this.offset = this.offset + this.limit // 设置下一页
            }
            console.log(this.tableData, this.total)
          })
          .finally(() => {
            this.loading = false
          })
      }
    },
    reset () {
      this.offset = 0
      this.tableData = []
      this.infiniteId += 1
    }
  }
}

四、手动加载下一页

运用el-table的插槽append设置一个加载按钮,手动触发页面加载

  • template

  • script
export default {
  name: 'WbTable',
  props: {
    // 服务端列表数据接口名称
    url: {
      type: String,
      required: true
    },
    // 服务端列表数据接口请求参数
    params: {
      type: Object,
      required: true
    },
    height: {
      type: [String, Number],
      default () {
        return 0
      }
    }
  },
  data () {
    return {
      tableData: [],
      loading: false,
      total: 0,
      isOver: false,
      isError: false,
      noMore: false
    }
  },
  created () {
    this.limit = this.params.limit ? this.params.limit : 8
    this.offset = this.params.offset ? this.params.offset : 0
    // 取设置的高度,否则按最小高度计算
    this.tableHeight = this.height ? this.height : this.limit * 45 + 80
    this.append(this.params)
  },
  methods: {
    // 列表新增
    async append (params) {
      this.loading = true
      this.$http[this.url]({
        ...params,
        offset: this.offset,
        limit: this.limit
      })
        .then(result => {
          if (!result.data) {
            this.noMore = true
            return
          }
          this.tableData = [
            ...this.tableData,
            ...result.data.rows
          ]
          this.total = result.data.total || 0
          console.log(this.tableData, this.total)
          //  判断是否需要加载下一页
          if (this.tableData.length >= this.total) {
            this.isOver = true
          }
        })
        // eslint-disable-next-line handle-callback-err
        .catch(error => {
          this.isError = true
        })
        .finally(() => {
          this.loading = false
        })
    },
    reset () {
      debugger
      this.offset = 0
      this.tableData = []
      this.total = 0
      this.isOver = false
      this.isError = false
      this.noMore = false
      // api动态加载完 开始重新请求数据
      this.$nextTick(() => {
        this.append(this.params)
      })
    },
    nextPage (event) {
      if (!this.isOver) {
        this.offset = this.offset + this.limit
        this.$nextTick(() => {
          this.append(this.params)
        })
      }
    }
  }
}
  • style


你可能感兴趣的:(vue-element(四) el-table滚动加载)