# Vue + ElementUI+ el-autocomplete 组件的防抖方案的懒加载
在项目开发中,经常会使用到下拉选择框,为了更快捷所以有了autocomplete的出现,autocomplete 是一个可带输入建议的输入框组件,该组件在数据量大的情况下能通过输入快速的查找到对应的选项。
通过Element-UI的官网文档的示例可知,其通过输入数据从而自动查找且显示对应的数据。   
                                           

数据量大的时候,此时加载数据时间长,影响用户体验,故通过数据的懒加载的形式显示数据,且如果只对其进行懒加载处理,其滚动到底的时候,会对其多次触发,不符合需求,且多次发起请求,时间长。通过对滚动事件进行防抖处理。

防抖为:当触发事件时,设定一个时间周期,如果在这个时间周期内事件被再次触发,则不予执行,时间周期更新。只有当时间周期到了后,才能被再次ch

<template>
  <div class="app">
    <el-autocomplete v-model="query.name"
                     clearable
                     v-loading="loading"
                     ref="autocomplete"
                     v-scrollLoad="load"
                     :fetch-suggestions="querySearch"
                     placeholder="请输入用户名称"
                     @select="handleSelect"></el-autocomplete>
  </div>
</template>
<script>
import { getData } from 'url路径';
export default {
    data() {
        return {
            //请求参数
            query: {
                name: '',
                pageNum: 0,
                pageSize: 10
            },
            //数据量计数
            suppilerListTotal = 0,
            //表单数据
            form: {}
        };
    },
    //自定义指令
    directives: {
        //用户选择栏的懒加载
        scrollLoad: {
            bind(el, binding, vnode) {
                //防抖函数
                function debounce(func, wait, immediate) {
                    //func函数,wait为时间周期
                    var timeout;
                    return function() {
                        var context = this,
                            args = arguments;
                        var later = function() {
                            timeout = null;
                            if (!immediate) {
                                func.apply(context, args);
                            }
                        };
                        var callNow = immediate && !timeout;
                        clearTimeout(timeout);
                        timeout = setTimeout(later, wait);
                        if (callNow) {
                            func.apply(context, args);
                        }
                    };
                }
                let wrapDom = el.querySelector('.el-autocomplete-suggestion__wrap');
                let listDom = el.querySelector('.el-autocomplete-suggestion__wrap  .el-autocomplete-suggestion__list');
                //将滚动事件通过参数传入防抖函数中
                var myEfficientFn = debounce(function() {
                    let condition = wrapDom.offsetHeight + wrapDom.scrollTop + 10 - listDom.offsetHeight;
                    if (condition > 0 && !vnode.context.loading) {
                        //滚动到底部则执行滚动方法load,binding.value就是v-scrollLoad绑定的值,加()表示执行绑定的方法
                        binding.value();
                    }
                }, 250);
                wrapDom.addEventListener('scroll', myEfficientFn, false); //绑定滚动事件
            }
        }
    },
    methods: {
        //滚到底部执行的方法
        load() {
            //如果数据量小于请求参数中的size,则表示请求数据已到底,无需继续请求
            if (this.suppilerListTotal < this.query.pageSize) {
                return false;
            }
            this.loading = true;
            this.query.pageSize += 50; //滑到底后将pageSize+50,即为请求数量+50
            //getData -滚动到底部后发起请求
            getData(this.query).then(res => {
                this.suppilerListTotal = res.datas.length; //将请求到的数组长度赋值给suppilerListTotal,用来存储数据量
                this.$refs['autocomplete'].$data.suggestions = res.datas; //将响应数据通过ref来进行实时更新
                this.loading = false;
            });
        },
        //新增用户时选择客户
        querySearch(queryString, cb) {
            //queryString为输入框的数据
            if (queryString) {
                //当输入框中有数据存在时
                this.query.name = queryString; //将数据赋给参数中的name
            } else {
                this.query.name = ''; //如果没值则将参数中的name赋空,防止二次选择,查不到全部的数据
            }
            //调用api接口
            getData(this.query).then(res => {
                this.suppilerListTotal = res.datas.length; //将请求到的数组长度赋值给suppilerListTotal,用来存储数据量
                cb(res.datas); //将响应数据中的数组通过cb回调函数传给组件
            });
        },
        //选择客户后将用户id传给表单
        handleSelect(item) {
            this.form.id = item.pkCustomer;
        }
    }
};
</script>

如有错误,望请海涵并指正。

Logo

前往低代码交流专区

更多推荐