el-select二次封装实现可分页加载数据

使用el-select时一次性渲染几百条数据时会造成页面克顿, 可以通过分页来实现, 这里我用的方式为默认获取全部数据, 然后一次性截取10条进行展示, 滚动条触底后会累加, 大家也可以优化为滚动条触底后发送请求去加载数据

  • 创建自定义指令customizeFocus用户懒加载
    在utils文件夹(大家可自定义)下创建customizeFocus.vue
import Vue from 'vue'

/**
 * 封装el-selectt懒加载指令
 * */
Vue.directive('customizeFocus',{
   
  bind(el,binding){
   
    let SELECT_DOM = el.querySelector(
      ".el-select-dropdown .el-select-dropdown__wrap"
    );
    SELECT_DOM.addEventListener("scroll", function () {
   
      let condition = this.scrollHeight - this.scrollTop <= this.clientHeight;

      if (condition) {
   
        binding.value();
      }
    });
  }
});
  • 创建select.vue文件用来编写分页加载代码
<template>
    <div>
        <el-select v-model="value1" collapse-tags :multiple="isMultiple" filterable :placeholder="placeholder"
                   v-customizeFocus="lazyloading" @change="submit()">
            <el-option v-for="item in stationOptions" :key="item.id" :label="item.label" :value="item.vBindValue">
                <span style="float: left;padding-right: 30px;">{
   {
    item.label }}</span>
                <span style="float: left;padding-right: 30px;">id:-{
   {
    item.id }}</span>
                <span style="float: right; color: #8492a6; font-size: 13px">{
   {
    item.describe }}</span>
            </el-option>
        </el-select>
    </div>
</template>

<script>
/**
 * cur:每页显示多少条, 默认值: 10, 类型: number
 * stationDataList: 已选择的数据, 默认值: [], 类型: array
 * isMultiple: 是否多选, 默认值: false, 类型: boolean
 * returnValue: 返回值内容, 默认值: 数据id, 类型: string
 * placeholder: 提示, 默认值: 请选择, 类型: string
 * */
export default {
   
    name: "selectModel",
    data() {
   
        return {
   
            value1: null,
            // el-select展示的数据
            stationOptions: [],
            // 全部数据
            stationAll: [],
            // 测点懒加载分页
            stationLazy: {
   
                startCur: 0,
                // 当前页码数据
                pageNum: 1,
            },
            stationData: this.stationDataList
        }
    },
    props: {
   
        isMultiple: {
   
            default: false,
            type: Boolean
        },
        stationDataList: {
   
            default: Array,
            type: Array
        },
        placeholder: {
   
            default: '请选择',
            type: String
        },
        returnValue: {
   
            default: 'id',
            type: String
        },
        cur: {
   
            default: 10,
            type: Number
        }
    },
    mounted() {
   
        this.getStationAll();
    },
    methods: {
   
        /**
         * 获取全部测点数据
         * */
        getStationAll() {
   
        	let returnValue = this.returnValue;
        
            for (let i = 0; i < 100; i++) {
   
                let obj = {
   
                    label: 'test_tag' + i+1,
                    id: i+1,
                    describe: 'test_tag' + i+1 + '描述'
                };
                this.stationAll.push(obj);
            }

			// 设置el-option的value绑定值
            if (this.stationAll && this.stationAll.length){
   
                this.stationAll.forEach(item=>{
   
                    item['vBindValue'] = item[returnValue]
                })
                
				this.stationOptions = this.stationAll.slice(this.stationLazy.startCur, this.cur);
	
	            // 查看
	            this.matchingData();
            }
            
        },

        /**
         * 匹配stationData里的数据,将其显示到下拉列表中
         * */
        matchingData(){
   
            if (this.stationData && this.stationData.length){
   
                this.value1 = [];
                let returnValue = this.returnValue;
                // 1.先查看当前显示的option里是否存在,如果不存在,从全部数据里获取
                this.stationData.forEach(eachItem=>{
   
                    let stationIndex = this.stationOptions.map(mapItem=>mapItem[returnValue]).indexOf(eachItem);
                    if (stationIndex !== -1){
   
                        this.value1.push(this.stationOptions[stationIndex][returnValue]);
                    } else {
   
                        let stationAllIndex = this.stationAll.map(mapItem=>mapItem[returnValue]).indexOf(eachItem);
                        if (stationAllIndex !== -1){
   
                            this.stationOptions.push(this.stationAll[stationAllIndex]);
                            this.value1.push(this.stationAll[stationAllIndex][returnValue]);
                        }
                    }
                })
            }
        },

        /**
         * 滚动条触底时触发此方法
         * */
        lazyloading() {
   
            if (this.stationAll.length > 0){
   
                // 计算总数据共有多少页
                let total = Math.ceil(this.stationAll.length / this.cur);
                // 如果计算总页码数小于等于当前页码数证明已到最后一页
                if (total <= this.stationLazy.pageNum){
   
                    return console.log('已加载全部数据');
                }

                this.stationLazy.pageNum ++;
                this.stationOptions = this.stationAll.slice(this.stationLazy.startCur, this.cur * this.stationLazy.pageNum);
                this.matchingData();
            }
        },

        /**
         * 提交
         * */
        submit(){
   
            this.stationData = JSON.parse(JSON.stringify(this.value1));
            this.$emit('callBackData',this.stationData)
        },
    }
}
</script>

<style scoped>

</style>
  • 在主文件里使用,
<template>
  <div>
    <selectModel :stationDataList="stationDataList" v-if="stationDataList.length" :isMultiple="true" @callBackData="callBackData"></selectModel>
  </div>
</template>

<script>
  import selectModel from '../../components/select/index'
  export default {
   
    name: "index",
    components:{
   
      selectModel
    },
    data(){
   
      return {
   
        stationDataList: [1,2,3,50,100], // 模拟获取出来的数据,数据id
      }
    },
    mounted(){
   
    },
    methods:{
   
        /**
         * 返回值
         * */
        callBackData(e){
   
            console.log(e,'eeeeeeeeeee')
        }
    }
  }
</script>

<style scoped>

</style>

最近更新

  1. TCP协议是安全的吗?

    2023-12-20 07:02:05       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2023-12-20 07:02:05       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2023-12-20 07:02:05       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2023-12-20 07:02:05       20 阅读

热门阅读

  1. 【RocketMQ-Bug】RocketMQ 在使用中的常见问题

    2023-12-20 07:02:05       44 阅读
  2. Spring Boot测试 - JUnit整合及模拟Mvc

    2023-12-20 07:02:05       38 阅读
  3. ubuntu22.04制作pycharm的桌面快捷方式

    2023-12-20 07:02:05       35 阅读
  4. 单元测试框架jUnit

    2023-12-20 07:02:05       42 阅读
  5. 漫谈UNIX、Linux、UNIX-Like

    2023-12-20 07:02:05       32 阅读
  6. ModBus TCP

    2023-12-20 07:02:05       33 阅读
  7. word的docx模板导出,poi

    2023-12-20 07:02:05       41 阅读