el-select 下拉框增加滾動(dòng)條滾到底部加載分頁數(shù)據(jù)

第一步,創(chuàng)建select-load-more.js文件

// 定義全局自定義指令
import Vue from 'vue'

const selectLazyLoad = function(Vue) {
  // el-select組件數(shù)據(jù)過多,使用翻頁加載數(shù)據(jù)指令
  Vue.directive('selectLazyLoad', {
    bind(el, binding) {
      const SELECT_WRAP_DOM = el.querySelector('.el-select-dropdown .el-select-dropdown__wrap')
      SELECT_WRAP_DOM.addEventListener('scroll', function() {
        // toFixed:把this.scrollTop轉(zhuǎn)換為整數(shù),兼容不同版本瀏覽器
        const condition = this.scrollHeight - this.scrollTop.toFixed(0) <= this.clientHeight
        if (condition) binding.value()
      })
    }
  })
}

if (window.Vue) {
  Vue.use(selectLazyLoad)
}

export default selectLazyLoad

第二步, 在main.js中注冊(cè)引入自定義指令

import selectLazyLoad from './directive/select-load-more'    //引入
Vue.use(selectLazyLoad)    // 使用自定義指令

第三步, 創(chuàng)建公共組件并在組件中使用自定義指令v-selectLazyLoad

<template v-slot>
  <el-select
    v-model="currentBranchNumber"
    v-selectLazyLoad:pageNum="loadMoreData(pageNum)"
    class="w-72"
    :dropdown-style="{maxHeight: '400px', overflow: 'auto'}"
    placeholder="可根據(jù)機(jī)構(gòu)ID或機(jī)構(gòu)名稱篩選"
    filterable
    clearable
    remote
    :remote-method="onSearch"
    :loading="loading"
    @clear="clearSelect"
    @focus="focusSelect"
  >
    <el-option v-for="item in branchTreeData" :key="item.id" :label="item.name" :value="item.id" />
  </el-select>
</template>

<script>
import axios from 'axios'
export default {
  name: 'BranchTreeSelect',
  props: {
    branchNumber: {
      type: String,
      default: ''
    }
  },
  data() {
    return {
      branchTreeData: [],
      pageNum: 1,
      currentBranchNumber: '',
      allowSearchFlag: true, // 是否允許檢索, 防止連續(xù)輸入時(shí)未組裝好數(shù)據(jù)就再次檢索
      loading: false,
      queryParam: { // 查詢后端所用參數(shù)對(duì)象, 可根據(jù)自己需求變更請(qǐng)求參數(shù)對(duì)象
        'xCode': '', // 模糊檢索code
        'xName': '', // 模糊檢索name
        'xParentCode': 'AYBBRNNO',
        'xType': '',
        'xFormat': 'Y',
        'xPage': 1,
        'xPageSize': 50
      }
    }
  },
  watch: {
    'currentBranchNumber': { // 選中數(shù)據(jù)改變時(shí),調(diào)用父組件的setBranchNumber方法,并傳入選中的值
      handler(val) {
        if (val) {
          this.$emit('setBranchNumber', this.currentBranchNumber.toString().split(':')[0])
        } else {
          this.$emit('setBranchNumber', '')
        }
      }
    },
    'pageNum': { // 當(dāng)前頁數(shù)改變時(shí), 重新觸發(fā)查詢
      handler(val) {
        if (val) {
          this.queryParam.xPage = val
          this.queryBranchData('', true)
        }
      }
    }
  },
  created() { // 組件實(shí)例創(chuàng)建后(data和methods已經(jīng)初始化完畢), 請(qǐng)求后端數(shù)據(jù)
    this.queryBranchData()
  },
  methods: {
    loadMoreData() { // 數(shù)據(jù)到底部繼續(xù)滑動(dòng),會(huì)自動(dòng)觸發(fā)頁數(shù)+1
      return () => {
        this.pageNum += 1
      }
    },
    onSearch(val) { // 檢索功能, 后端可以支持模糊檢索
      if (val) {
        if (this.allowSearchFlag && val.length > 2) { // 輸入超過兩個(gè)字符進(jìn)行檢索
          this.allowSearchFlag = false
          this.branchTreeData = []
          this.queryParam.xPage = 1
          this.queryBranchData(val)
        }
      }
    },
    queryBranchData(param, appendFlag) { // 請(qǐng)求后端數(shù)據(jù)
      const cacheUrl = 'http://XXXXXXXXX.uat.cn/cache/queryParamPager'
      if (!isNaN(parseInt(param)) && isFinite(param)) {
        this.queryParam['xCode'] = param
      } else if (param && param.trim() !== '') {
        this.queryParam['xName'] = param
      }
      axios.post(cacheUrl, this.queryParam, {
        headers: { 'Content-Type': 'application/json' },
        withCredentials: false
      }).then(res => {
        if (res.data.code === 200 && res.data.data.list.join() !== '') { // 如果后端返回?cái)?shù)據(jù)有值
          if (appendFlag) { // 是否拼接數(shù)據(jù)
            this.branchTreeData = this.branchTreeData.concat(res.data.data.list)
          } else {
            this.branchTreeData = res.data.data.list
          }
          this.allowSearchFlag = true
          this.loading = false
        }
      }).catch(err => console.error(`獲取機(jī)構(gòu)參數(shù)異常, ${err}`))
    },
    clearSelect() { // 清空下拉框選中的值,會(huì)向后端重新查詢第一頁的數(shù)據(jù)
      this.queryParam['xCode'] = ''
      this.queryParam['xName'] = ''
      this.queryParam.xPage = 1
      this.branchTreeData = []
      this.queryBranchData()
    },
    focusSelect() { // 光標(biāo)觸發(fā)下拉框時(shí),如果下拉框數(shù)據(jù)為空,則向后端查詢第一頁數(shù)據(jù)
      if (this.branchTreeData.join() === '') {
        this.queryParam['xCode'] = ''
        this.queryParam['xName'] = ''
        this.queryBranchData()
      }
    }
  }
}
</script>

<style scoped>

</style>

第四步, 在父組件中引入第三步創(chuàng)建的子組件

// 使用第三步創(chuàng)建的子組件
<branch-tree-select ref="accBranchRef" :branch-number="QueryProtocolListX1.accBranch" @setBranchNumber="setAccBranchNumber" />

// 引入子組件
import BranchTreeSelect from '@/components/BranchTreeSelect'

components: {
    BranchTreeSelect
}

mothods: {
    setAccBranchNumber(val) {
      // val就是子組件選中的值
    }
}

以上內(nèi)容四個(gè)步驟從下面鏈接復(fù)制https://devpress.csdn.net/vue/66caf7da8f4f502e1cfda77e.html

以下內(nèi)容四個(gè)步驟從下面鏈接復(fù)制
https://www.cnblogs.com/caihongmin/p/17920859.html
自定義指令

import { debounce } from "lodash";
export default {
    inserted(el, binding, vnode) {
        // 獲取滾動(dòng)容器dom
        let scrollWrap = el.querySelector('.el-select-dropdown .el-scrollbar .el-select-dropdown__wrap')
        // 把監(jiān)聽的句柄防抖一下
        const handle = debounce((e) => {
            let scrollDistance = scrollWrap.scrollHeight - scrollWrap.scrollTop
            // 比如此處預(yù)留6個(gè)像素的位置用于觸底
            if (scrollWrap.clientHeight + 6 > scrollDistance) {
                binding.value() // 觸底通知一下,外界
            }
        }, 170)
        // 綁定監(jiān)聽滾動(dòng)事件
        scrollWrap?.addEventListener('scroll', handle)
        // 把監(jiān)聽的句柄掛載到元素身上便于解綁時(shí)使用
        el._hanlde = handle
    },
    unbind() {
        // 獲取滾動(dòng)容器dom
        let scrollWrap = el.querySelector('.el-select-dropdown .el-scrollbar .el-select-dropdown__wrap')
        // 解綁
        scrollWrap?.removeEventListener('scroll', el._hanlde)
        // 清空
        delete el._hanlde;
    }
}

給el-select使用這個(gè)自定義指令

<template>
  <div class="box">
    <el-select v-model="value" filterable :popper-append-to-body="false" v-down="loadmore" clearable>
      <el-option v-for="item in options" :key="item.id" :label="item.name" :value="item.id">
      </el-option>
    </el-select>
  </div>
</template>

<script>
import axios from "axios";
export default {
  data() {
    return {
      options: [],
      value: '',
      pageIndex: 1,
      pageSize: 20
    };
  },
  mounted() {
    this.getOptions()
  },
  methods: {
    async getOptions() {
      // 筆者自己的服務(wù)器,給大家提供了一個(gè)分頁接口
      let url = `http://ashuai.work/api/pageData?pageIndex=${this.pageIndex}&pageSize=${this.pageSize}`
      let { data } = await axios.get(url)
      if (data.length == 0) return this.$message('沒數(shù)據(jù)了')
      // 合并一下下拉框數(shù)據(jù)
      this.options = [
        ...this.options,
        ...data
      ]
    },
    // 觸底了,繼續(xù)發(fā)請(qǐng)求
    loadmore() {
      this.pageIndex = this.pageIndex + 1
      this.getOptions()
    },
  },
};
</script>
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容