目录

 

技术栈版本

问题概述

directive2.0和3.0的生命周期对比

上拉加载实现代码(附完整组件代码)

最终实现效果gif


 

技术栈版本

vue版本:3.0.7

element-plus:1.0.2

 

问题概述

项目用到element-plus框架的el-select组件,由于数据量过大需要做分页加载,发现vue无法触发directives里面的bind方法,经过排查是由于vue3.0做了改版,跟2.0生命周期不一样

 

directive2.0和3.0的生命周期对比

directive2.0生命周期

 

directive3.0生命周期


 

 

上拉加载实现代码(附完整组件代码)

paginationSelect.vue组件

<template>
    <div class="pagination-select-component">
        <el-select :popper-class="select_config.popperClass" v-model="select_config.id" placeholder="请选择" v-loadmore="loadmore" @change="onChange" >
            <el-option v-for="(item,index) of select_config.list" :index="index" :key="item[key]" :label="item[label]" :value="item[value]" v-loading="index == select_config.list.length-1 && select_config.loading"></el-option>
        </el-select>
    </div>
</template>
<script>
export default {
    name:'pagination-select-component',
    props:{
        key:{
            type:String,
            default:'id'
        },
        value:{
            type:String,
            default:'id'
        },
        label:{
            type:String,
            default:'name'
        }
    },
    data(){
        return{
            select_config:{
                id:'',
                list:[],
                pagination:{
                    page:1,
                    page_size:10,
                    total:0
                },
                popperClass:'popper-class'+Date.now()
            }
        }
    },
    directives: {
        'loadmore': {
            beforeMount(el, binding) { 
                const SELECTWRAP_DOM = document.querySelector(`.${binding.instance.select_config.popperClass} .el-select-dropdown .el-select-dropdown__wrap`);
                if(!SELECTWRAP_DOM){
                    return;
                }
                SELECTWRAP_DOM.addEventListener('scroll', function () {
                    const condition = this.scrollHeight - this.scrollTop <= this.clientHeight;
                    if (condition) {
                        binding.value();
                    }
                });
            }
        }
    },
    mounted(){
        this.$nextTick(()=>{
            this.getList()
        })
    },
    methods:{
        /**
         * 调用列表数据
         */
        getList(){
            this.apiFn({
                page:this.select_config.pagination.page,
                pageSize:this.select_config.pagination.page_size,
                keyword:'',
                status:0
            }).then(res=>{
                this.select_config.list = this.select_config.list.concat(res.data.list)
                this.select_config.pagination.total = res.data.total
            })
        },
        /**
         * 数据api(组件外部初始化此函数)
         */
        apiFn(){},
        /**
         * 上拉加载更多
         */
        loadmore(){
            this.select_config.pagination.page++
            if(this.select_config.list.length < this.select_config.pagination.total){
                this.getList()
            }
        },
        /**
         * 返回选中id
         */
        onChange(){
            this.$emit('change',this.select_config.id)        
        }
    }
}
</script>

 

index.vue页面

<template>
    <pagination-select-component ref="paginationSelect" @change="(id)=>{search_config.id=id}"/>
</template>
<script>
import { inventoryManagementApi } from '@/api'
import paginationSelectComponent from '@/components/paginationSelect'
export default {
    components:{
        paginationSelectComponent
    },
    data(){
        return{
            search_config:{
                id:""
            }
        }
    },
    mounted(){
        this.$refs.paginationSelect.apiFn = this.getListApi()
    },
    methods:{
        /**
         * 提供api给pagination-select组件
         */
        getListApi(){
            return inventoryManagementApi.supplierList(params)
        }
    }
}

 

最终实现效果gif

 

Logo

前往低代码交流专区

更多推荐