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可分页加载数据的资料请关注脚本之家其它相关文章!

相关文章

  • 关于pinia的使用和持久化方式(pinia-plugin-persistedstate)

    关于pinia的使用和持久化方式(pinia-plugin-persistedstate)

    本文介绍了Pinia的使用方法,包括安装和配置插件pinia-plugin-persistedstate,以及在项目中创建和使用Store模块,同时,还讲解了Pinia的state、getters和actions的使用,并提供了在uniapp中使用持久化插件的总结
    2025-02-02
  • 如何利用Vue3+Element Plus实现动态标签页及右键菜单

    如何利用Vue3+Element Plus实现动态标签页及右键菜单

    标签页一般配合菜单实现,当你点击一级菜单或者二级菜单时,可以增加对应的标签页,当你点击对应的标签页,可以触发对应的一级菜单或者二级菜单,下面这篇文章主要给大家介绍了关于如何利用Vue3+Element Plus实现动态标签页及右键菜单的相关资料,需要的朋友可以参考下
    2022-11-11
  • 浅析在Vue中watch使用的必要性及其优化

    浅析在Vue中watch使用的必要性及其优化

    这篇文章主要来和大家深入讨论一下在Vue开发中是否有必要一定用watch,如果换成watcheffect会如何,文中的示例代码讲解详细,需要的可以参考下
    2023-12-12
  • Vue.js 2.0 移动端拍照压缩图片预览及上传实例

    Vue.js 2.0 移动端拍照压缩图片预览及上传实例

    这篇文章主要介绍了Vue.js 2.0 移动端拍照压缩图片预览及上传实例,本来移动端开发H5应用,准备将mui框架和Vue.js+vue-router+vuex 全家桶结合起来使用
    2017-04-04
  • vue与bootstrap实现时间选择器的示例代码

    vue与bootstrap实现时间选择器的示例代码

    本篇文章主要介绍了vue与bootstrap实现时间选择器的示例代码,非常具有实用价值,需要的朋友可以参考下
    2017-08-08
  • ElementUI下拉组件el-select一次从后端获取选项并设置默认值方式

    ElementUI下拉组件el-select一次从后端获取选项并设置默认值方式

    这篇文章主要介绍了ElementUI下拉组件el-select一次从后端获取选项并设置默认值方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-01-01
  • Vue.js轮播图走马灯代码实例(全)

    Vue.js轮播图走马灯代码实例(全)

    这篇文章主要介绍了Vue.js轮播图走马灯,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-05-05
  • vue-resource 拦截器使用详解

    vue-resource 拦截器使用详解

    本篇文章主要介绍了vue-resource 拦截器使用详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-02-02
  • vue+elementUI实现点击左右箭头切换按钮功能

    vue+elementUI实现点击左右箭头切换按钮功能

    这篇文章主要介绍了vue+elementUI实现点击左右箭头切换按钮功能,样式可以根据自己需求改动,感兴趣的朋友可以参考下实现代码
    2024-05-05
  • 解读Vue-loader的相关知识

    解读Vue-loader的相关知识

    这篇文章主要介绍了解读Vue-loader的相关知识,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-03-03

最新评论