select懒加载

1,095 阅读1分钟

前段时间后台提出的需求,希望select可以下拉滑动去懒加载数据。以下是参考网上很多案例,做出的总结。

思路

  1. 下拉到底部再去请求数据
  2. 判断是否下拉到底部
  3. 拿取父级元素

解题

解题就是倒着来看思路

首先,拿取父级元素,因为涉及到dom底层操作,在这块儿可以使用vue的自定义指令的方法对普通 DOM 元素进行底层操作。

局部自定义指令使用方法

image.png

拿取父级元素

 const SELECTWRAP_DOM = el.querySelector('.el-select-dropdown .el-select-dropdown__wrap')

判断是否下拉到底部

SELECTWRAP_DOM.addEventListener('scroll', function () {
/**
* scrollHeight 获取元素内容高度(只读)
* scrollTop 获取或者设置元素的偏移值,常用于, 计算滚动条的位置, 当一个元素的容器没有产生垂直方向的滚动条, 那它的scrollTop的值默认为0.
* clientHeight 读取元素的可见高度(只读)
* 如果元素滚动到底, 下面等式返回true, 没有则返回false:
* ele.scrollHeight - ele.scrollTop === ele.clientHeight;
*/
const condition = this.scrollHeight - this.scrollTop <= this.clientHeight
if (condition) {
    binding.value()
}

请求数据

loadmore () {
    if (this.formData.pageIndex > this.formData.totalPage) {
      return false
    }
    this.getprojectList()
},

完整代码

<template>
  <el-select ref="select" v-model="projectIdDefault" 
    popper-class="essentialInformation-select"
    clearable 
    filterable
    :default-first-option='true'
    v-el-select-loadmore="loadmore"
    style="width:100%">
      <el-option
        v-for="item in projectList"
        :key="item.project_id"
        :label="item.name"
        :value="`${item.project_id},${item.name}`">
      </el-option>
  </el-select>
</template>

<script>
  import { getProjectList } from '@/utils/dataDictionaryApi'
  export default {
    props: {
      projectId: {
        type: String,
        default: ''
      }
    },
    data () {
      let that = this
      return {
        projectIdDefault: that.projectId,
        projectList: [],
        formData: {
          pageIndex: 1,
          pageSize: 5,
          totalPage: 0
        }
      }
    },
    directives: {
      'el-select-loadmore': {
        bind (el, binding) {
          // 获取element-ui定义好的scroll盒子
          const SELECTWRAP_DOM = el.querySelector('.el-select-dropdown .el-select-dropdown__wrap')
          // console.log(SELECTWRAP_DOM, 'SELECTWRAP_DOM')
          SELECTWRAP_DOM.addEventListener('scroll', function () {
            /**
            * scrollHeight 获取元素内容高度(只读)
            * scrollTop 获取或者设置元素的偏移值,常用于, 计算滚动条的位置, 当一个元素的容器没有产生垂直方向的滚动条, 那它的scrollTop的值默认为0.
            * clientHeight 读取元素的可见高度(只读)
            * 如果元素滚动到底, 下面等式返回true, 没有则返回false:
            * ele.scrollHeight - ele.scrollTop === ele.clientHeight;
            */
            const condition = this.scrollHeight - this.scrollTop <= this.clientHeight
            if (condition) {
              binding.value()
            }
          })
        }
      }
    },
    watch: {
      projectId (newCity, oldCity) {
        this.projectIdDefault = newCity
      },
      projectIdDefault (newCity, oldCity) {
        if (!newCity || newCity === oldCity) {
          // 如果新的字段是空串或者新的等于旧的
          return false
        }
        this.$emit('changeProjectId', newCity)
      }
    },
    methods: {
      loadmore () {
        if (this.formData.pageIndex > this.formData.totalPage) {
          return false
        }
        this.getprojectList()
      },
      getprojectList () {
        getProjectList({
          'page': this.formData.pageIndex,
          'limit': this.formData.pageSize,
          'dim': this.projectIdDefault.split(',')[1]
        }).then(res => {
          this.$nextTick(() => {
            this.projectList = this.projectList.concat(res.data.page.list)
            this.formData.pageIndex = res.data.page.currPage + 1
            this.formData.totalPage = res.data.page.totalPage
          })
        })
      }
    },
    created () {
      this.projectList = []
      this.getprojectList()
    }
  }
</script>

<style>
.essentialInformation-select .el-select-dropdown__wrap{
  max-height: 150px;
  overflow: scroll;
}
</style>

缺点

  1. 模糊搜索只能搜索已查询出来的数据
  2. 编辑的时候,数据无法回显未加载出来的数据