el-select实现的下拉分页组件

基于element-ui的el-select实现的下拉分页组件

<template>
  <div>
    <el-select
      v-model="selectOption"
      :value="value"
      v-bind="$attrs"
      :remote-method="remoteSearch"
      :loading="loadings"
      loading-text="加载中..."
      @change="handleChange"
      @visible-change="visibleChange"
    >
      <div v-infinite-scroll="loadScroll">
        <el-option
          v-for="item in dataList"
          :key="item[valueName]"
          :value="item[valueName]"
          :label="item[labelName]"
        />
      </div>
    </el-select>
  </div>
</template>

<script>
import request from '@/utils/request'
export default {
  props: {
    // 输入的值
    value: {
      type: [String, Array, Number],
      default: null
    },
    // 请求的url
    url: {
      type: String,
      default: ''
    },
    // value值的名称,默认值value
    valueName: {
      type: String,
      default: 'value'
    },
    // label值的名称,默认值text
    labelName: {
      type: String,
      default: 'text'
    },
    // 配置的请求参数
    requestParam: {
      type: Object,
      default: () => {
        return {}
      }
    },
    // 回显的数据
    visibleOption: {
      type: Array,
      default: () => {
        return []
      }
    }
  },
  data() {
    return {
      dataList: [], // 获取的列表数据
      selectOption: '', // 输入框的值
      pagination: { // 分页参数
        curPage: 0,
        pageSize: 15
      },
      noMore: false, // 是否有下一页
      queryKeyword: '', // 搜索的关键词
      loadings: false // 加载的loading
    }
  },
  watch: {
    // 输入的值
    value: {
      handler(value) {
        this.selectOption = value || ''
      },
      immediate: true
    },
    // 回显的值变化
    visibleOption: {
      handler(value) {
        this.dataList = value
      },
      immediate: true
    }
  },
  methods: {
    // 获取列表数据
    getList(value) {
      this.loadings = true
      this.queryKeyword = value || ''
      request.post(this.url, {
        queryKeyword: this.queryKeyword,
        ...this.pagination,
        ...this.requestParam
      }).then(({ flag, data: { dataList, totalRows }}) => {
        if (flag === 1) {
          if ((this.pagination.curPage * this.pagination.pageSize + dataList.length) < totalRows) {
            this.dataList = this.dataList.concat(dataList)
            this.noMore = false
          } else if ((this.pagination.curPage * this.pagination.pageSize + dataList.length) === totalRows) {
            this.dataList = this.dataList.concat(dataList)
            this.noMore = true
          } else {
            this.noMore = true
          }
          // 去重
          if (this.visibleOption.length) {
            this.dataList = [...this.visibleOption, ...this.dataList]
            const map = new Map()
            const list = []
            this.dataList.forEach((item) => {
              if (map.has(item[this.valueName])) {
                map.set(item[this.valueName], true)
              } else {
                map.set(item[this.valueName], false)
                list.push(item)
              }
            })
            this.dataList = list
          }
        }
        this.loadings = false
      })
    },
    // 选中的值变化
    handleChange(data) {
      this.$emit('input', data)
      this.$emit('change', data)
    },
    // 远程搜索方法
    remoteSearch(value) {
      this.dataList = []
      this.noMore = false
      this.pagination.curPage = 0
      this.getList(value)
    },
    // 下拉框出现时
    visibleChange(visible) {
      if (!visible) {
        this.queryKeyword = ''
        this.noMore = false
        this.dataList = []
        this.pagination.curPage = 0
      } else {
        this.getList(this.queryKeyword)
      }
    },
    // 滚动获取数据
    loadScroll() {
      if (!this.noMore) {
        this.pagination.curPage++
        this.getList(this.queryKeyword)
      }
    }
  }
}
</script>

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值