当前位置: 首页 > article >正文

vue3+elPlus 选择框select 下拉数据过千条,页面卡顿,分页解决

vue3+elPlus 选择框select 下拉数据过千条,页面卡顿,分页解决
注意:我这里是提前将下拉数据请求到,保存到本地,来分页
也可分页请求接口来获取,性质一样

最重要的是,监听滑动到底部的vue指令

v-loadmore=“selectListPageHandle”

在文件中directive—loadmore—index.tx
自定义指令

import { Directive, DirectiveBinding } from 'vue'
/**
 * 操作权限处理
 */
export const loadmore: Directive = {
  beforeMount(el: HTMLElement, binding: DirectiveBinding) {
    let classDirect = el.className.split(" ")[1]
    const selectDom = document.querySelector(`.event-select-poper${classDirect} .el-scrollbar__wrap`)
    let loadMores = function () {
      const isBase = this.scrollHeight - this.scrollTop <= this.clientHeight + 20
      if (isBase) {
        // 增加防抖
        binding.value && binding.value()
      }
    }
    // 将获取到的dom和函数挂载到el-select上,实例销毁时好处理
    el.selectDomInfo = selectDom
    el.selectLoadMore = loadMores
    // 监听滚动事件
    selectDom?.addEventListener('scroll', loadMores.bind(selectDom))
  },
  // 实例销毁
  beforeUnmount(el) {
    if (el.selectLoadMore) {
      el.selectDomInfo.removeEventListener('scroll', el.selectLoadMore)
      delete el.selectDomInfo
      delete el.selectLoadMore
    }
  }
}

导入全局Index.ts

import { loadmore } from './loadmore'
import { App } from 'vue';
export default (app: App) => {

  app.directive('loadmore', loadmore);

};

// 自定义指令
main.ts中引入(百度怎么引入全局指令,这里不详细说了)

import directive from '@/directive';
// 自定义指令
directive(app)

直接贴代码

// 封装的组件
<template>
  <el-combo-box
    :popper-class="'event-select-poper'+directCustom"
    :class="directCustom"
    v-loadmore="selectListPageHandle"
    style="width: 100%"
    v-model="valueName"
    filterable
    remote
    :remote-method="remoteMethod"
    :loading="loading"
    :dropdown-visible-always="true"
    :show-option-tooltip="true"
    @focus="focusChange"
    @change="selectChange"
  >
    <el-option
      v-for="dict in selectList"
      :key="dict.code"
      :label="dict.label"
      :value="dict.code"
    >
    </el-option>
  </el-combo-box>
</template>

<script setup lang="ts">
import { ref, watch, computed } from 'vue'
const props = defineProps({
  modelValue: [String, Object, Array],
  selectAllList: {
    type: Array,
    default: []
  },
  disabled: {
    type: Boolean,
    default: false
  },
  directCustom: {
    type: String,
    default: ''
  }
})
const emit = defineEmits(['update:modelValue', 'changeCallback'])
watch(
  () => props.modelValue,
  async (val) => {
    if (val) {
      // 回显默认值
      valueName.value = val
    } else {
      valueName.value = []
    }
  }
)

const selectList = ref<any>([])
const valueName = ref('')
const loading = ref(false)

// 本地分页方法
let pageSize = 10
let pageNumber = 1
const resetselectListInit = () => {
  pageNumber = 1 // 重置页数
  selectList.value = [] // 重置选项
  selectListPageHandle()
}
const selectListPageHandle = ($event) => {
  if (loading.value) {
    return false
  }
  // 数据加载完之后,不需要再获取
  if (selectList.value.length >= props.selectAllList.length) {
    return false
  }
  loading.value = true
  let resData = props.selectAllList.slice((pageNumber - 1) * pageSize, pageNumber * pageSize)
  selectList.value = selectList.value.concat(resData)
  pageNumber += 1
  //加载完成
  loading.value = false
}
// 本地过滤
const remoteMethod = (query: string) => {
  if (query) {
    // 手动触发下拉框回滚至顶部,避免触发v-selectLazyLoad指令
    // document.querySelector(`.el-select-dropdown__wrap`).scrollTop = 0;
    if (loading.value) {
      return false
    }
    loading.value = true
    selectList.value = props.selectAllList.filter((item) => {
      return item.codeAndName.toLowerCase().includes(query.toLowerCase())
    })
    loading.value = false
  } else {
    // 为空时,显示第一页数据
    resetselectListInit()
  }
}
const focusChange = () => {
  // 重置(显示第一页数据)
  resetselectListInit()
}
const selectChange = (data) => {
  emit('update:modelValue', data)
  emit('changeCallback', data)
}
</script>

<style scoped lang="scss"></style>

引用组件
import elComboxNew from ‘@/components/elComboxNew/index.vue’

<el-row>
   <el-col :span="12" class="left-form-gen">
       <el-form-item label="合同文本管理组织" prop="archivesDepartmentCode">
         <elComboxNew
           directCustom="archivesDepartmentCode"
           v-model="dataForm.archivesDepartmentCode"
           :selectAllList="archivesDepartmentCodeList"
         ></elComboxNew>
       </el-form-item>
     </el-col>
   </el-row>
// 请求所有数据
onMounted(() => {
  getArchivesDepartmentCodeList()
})

const archivesDepartmentCodeList = ref<any>([])
const getArchivesDepartmentCodeList = () => {
  return new Promise((resolve, reject) => {
    AJX_archivesDepartmentCodeList().then((res: any) => {
      let archivesDepartmentCodeListStore = res.data ?? []
      archivesDepartmentCodeList.value = archivesDepartmentCodeListStore.map((item) => {
        return {
          code: item.archivesDepartmentCode,
          label: item.archivesDepartmentCode + item.archivesDepartmentName
        }
      })
      resolve(true)
    })
  })
}

http://www.kler.cn/a/418895.html

相关文章:

  • Java之链表1
  • 【代码随想录|贪心算法02】
  • vscode ctrl+/注释不了css
  • 通俗易懂:序列标注与命名实体识别(NER)概述及标注方法解析
  • TiDB 调度概述
  • HTTPS 加密
  • Java中 HttpURLConnection 和 HttpClient 详解(初学者友好)
  • 【从零开始的LeetCode-算法】3208. 交替组 II
  • 【Git教程 之 版本控制】
  • 深入探讨SQL优化原理 - 增量查询和索引加速
  • JavaScript 高级教程:异步编程、面向对象与性能优化
  • EC2还原快照
  • 探索3D世界:使用 lib3ds 读取和解析 3DS 文件
  • CentOS使用chrony服务进行时间同步源设置脚本
  • CSS3网站
  • 欧拉函数——acwing
  • 挑战用React封装100个组件【005】
  • 【linux】(23)对象存储服务-MinIo
  • Linux 僵尸进程和孤儿进程, 进程优先级
  • Android 12.0新增自定义HIDL问题记录
  • 内网穿透步骤
  • Spring Data JPA(二) 高级进阶
  • linux——进程间通信及管道的应用场景
  • 蓝桥杯经验分享
  • 医院分诊管理系统|Java|SSM|VUE| 前后端分离
  • 2. STM32_中断