ElementUI的el-select加载分页

31 阅读1分钟

摘要:

针对数据量大的选择器,需要分页从后端接口,前端监听选择器下拉框的滚动事件,当往下滚动至底部一定位置时需要调用接口,可以通过指定以指令实现该功能。

指令的实现

import Vue from 'vue'

const elLoadMore = {
  inserted(element, binding, vnode) {
    const SELECTWRAP_DOM = element.querySelector(
      '.el-select-dropdown .el-select-dropdown__wrap'
    )
    let scrollPosition = 0
    SELECTWRAP_DOM.addEventListener('scroll', function () {
      // 当前的滚动位置 减去 上一次的滚动位置 
      // 如果为true则代表向上滚动,false代表向下滚动,判断不加的话会频繁触发滚动事件,引起bug
      const flag = this.scrollTop - scrollPosition > 0
      scrollPosition = this.scrollTop

      const LIMIT_HEIGHT = 10

      const CONDITION = this.scrollHeight - (this.scrollTop + this.clientHeight) < LIMIT_HEIGHT
      if (flag && CONDITION) {
        // 将滚动行为告诉组件
        binding.value && binding.value()
      }
    })
  }
}

const install = function(Vue) {
  Vue.directive('checkInt', elLoadMore)
}
if (Vue) {
  window.checkInt = elLoadMore
  Vue.use(install) // eslint-disable-line
}
export default elLoadMore

具体使用

  • html中使用
<el-select
  v-model="searchData.carrierIdList"
  placeholder="请选择承运商"
  filterable
  remote
  clearable
  multiple
  collapse-tags
  :remote-method="(query) => getOptionsDataList(query, true)"
  v-elLoadMore="getOptionsDataList"
  @visible-change="visibleChangeOptions"
>
   el-option v-for="item in optionsData" :value="item.value" :key="item.value" :label="item.label" />
</el-select>
  • 请求数据处理
export default {
  data() {
    return {      
      optionsData: [],
      optionsDataMore: false,
      optionsDataParams: {
        page: 0,
        size: 50,
        lastKeyword: undefined,
      },
    }
  },
  methods: {
    // 承运商下拉数据
    getOptionsDataList: debounce(async function (keyword, isReset) {
      keyword = keyword || undefined // 减少不必要的重复请求
      const isResetData = keyword !== this.optionsDataParams.lastKeyword || isReset
      if (isResetData) {
        this.optionsData = []
        this.optionsDataParams.page = 0
        this.optionsDataMore = false
      }
      this.optionsDataParams.lastKeyword = keyword

      // 没有更多
      if (this.optionsDataMore) { return }

      const res = await crmSupOptions({
        page: ++this.optionsDataParams.page,
        size: this.optionsDataParams.size,
        keyword: keyword,
      })

      const { records, total } = res.data || {}
      if (res?.code === '200') {
        const list = (records || []).map((item) => ({
          ...item,
          value: item.supplierId,
          label: item.supplierName,
        }))

        this.optionsData.push(...list)
        this.optionsMore = this.optionsDataParams.page * this.optionsDataParams.size >= total
       } else {
        this.$Message.error(res.msg || '请求失败')
      }
    }, 300),

    // 下拉框弹出重新加载数据
    visibleChangeOptions(val) {
      if (val) {
        this.getOptionsDataList('', true)
      } else {
        this.optionsData = []
      }
    }
  }
}