el-select二次封装实现可分页加载数据的示例代码

 更新时间:2023年12月20日 09:23:56   作者:酒渣  
使用el-select时一次性渲染几百条数据时会造成页面克顿, 可以通过分页来实现,所以本文给大家介绍了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>

以上就是el-select二次封装实现可分页加载数据的示例代码的详细内容,更多关于el-select可分页加载数据的资料请关注脚本之家其它相关文章!

相关文章

  • Vue3.3 + TS4构建实现ElementPlus功能的组件库示例

    Vue3.3 + TS4构建实现ElementPlus功能的组件库示例

    Vue.js 是目前最盛行的前端框架之一,而 TypeScript 则是一种静态类型言语,它能够让开发人员在编写代码时愈加平安和高效,本文将引见如何运用 Vue.js 3.3 和 TypeScript 4 构建一个自主打造媲美 ElementPlus 的组件库
    2023-10-10
  • vue+高德地图写地图选址组件的方法

    vue+高德地图写地图选址组件的方法

    这篇文章主要介绍了vue+高德地图写地图选址组件的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-05-05
  • Vue头像处理方案小结

    Vue头像处理方案小结

    这篇文章主要介绍了Vue头像处理方案,实现思路主要是通过获取后台返回头像url,判断图片宽度,高度。具体实例代码大家参考下本文
    2018-07-07
  • Vue动态面包屑功能的实现方法

    Vue动态面包屑功能的实现方法

    面包屑功能是我们在项目中经常遇到的功能,今天小编使用Element-UI 进行实现在vue项目中实现面包屑功能,具体实现方式大家跟随小编一起学习吧
    2019-07-07
  • vue实现页面刷新动画

    vue实现页面刷新动画

    这篇文章主要为大家详细介绍了vue实现页面刷新动画,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-04-04
  • vue bus全局事件中心简单Demo详解

    vue bus全局事件中心简单Demo详解

    ue-bus 提供了一个全局事件中心,并将其注入每一个组件,你可以像使用内置事件流一样方便的使用全局事件。这篇文章给大家介绍了vue bus全局事件中心简单Demo,需要的朋友参考下吧
    2018-02-02
  • 详解Nuxt.js部署及踩过的坑

    详解Nuxt.js部署及踩过的坑

    这篇文章主要介绍了详解Nuxt.js部署及踩过的坑,Nuxt.js 提供了两种发布部署应用的方式:服务端渲染应用部署 和 静态应用部署。本文主要说说服务端渲染应用部署,感兴趣的小伙伴们可以参考一下
    2018-08-08
  • 如何封装Vue Element的table表格组件

    如何封装Vue Element的table表格组件

    这篇文章主要介绍了如何封装Vue Element的table表格组件,帮助大家更好的理解和使用vue框架,感兴趣的朋友可以了解下
    2021-02-02
  • Hooks对于Vue作用意义详解

    Hooks对于Vue作用意义详解

    这篇文章主要为大家介绍了Hooks对于Vue作用意义详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-06-06
  • vue 过滤、模糊查询及计算属性 computed详解

    vue 过滤、模糊查询及计算属性 computed详解

    计算属性是vue里面为了简化在模板语法中对响应式属性做计算而存在的,这篇文章主要介绍了vue 过滤、模糊查询(计算属性 computed),需要的朋友可以参考下
    2022-11-11

最新评论