基于vue和element-ui的搜索下拉滚动条组件
  hr26MWkbkYWR 2023年11月02日 49 0

📒 背景

最近项目中需要制作一个下拉滚动分页的功能(如下图展示),今天分享一下这个组件功能。希望能抛砖引玉,给大家带来启发。

基于vue和element-ui的搜索下拉滚动条组件_分页

🔍需求功能

1.数据量大了就页面渲染缓慢从而卡顿严重,为了解决这个问题,对element-ui进行了改造,el-select改为分页滚动加载。

2.数据量大时下拉可以分页滚动加载,而且可以支持原来的搜索。

👣设计开发

先说一下我的开发环境版本:

基于vue和element-ui的搜索下拉滚动条组件_JSON_02

node: v11.3.0

npm: 6.4.1

vue:2.5.11

如果不是以上版本也没关系,今日分享的思路,相信你可以自己造出来~

1.先写html页面:

<div class="selectBox" v-clickoutside="handleClose">
            <i class="icon el-icon-arrow-down " :class="showdrop?'arrowtop':''"></i>
            <input type="text" :placeholder="$t('pageinfo.searchstore')"
                   ref="searchInput"
                   v-model="selectData.storeName"
                   @focus="showdropbox"
                   @blur="closedropbox"
                   @input="selectInput"
                    />
            <transition name="el-zoom-in-top">
                <div class="dropdown" v-if="showdrop" v-el-select-loadmore="load">
                    <div class="arrow"></div>
                    <div class="contentMore" v-show="loadTextBox" :style="storeidlist.length>7?'height:250px;':(storeidlist.length===0?'height:46px':'height:'+(storeidlist.length*34+12)+'px;')">
                        <el-scrollbar  style="height: 100%;max-height:250px;" ref="myscroll" class="myscroll" >
                            <ul  >
                                <li v-for="store in storeidlist" :class="store.storeId === SelectValue.storeId ?'selected ':''"
                                    @click="selectOne(store)">{{store.storeName}}</li>
 
                                <li v-if="storeidlist.length==0" style="display: inline-block;">{{$t('pageinfo.nosearchdata')}}</li>
                            </ul>
                        </el-scrollbar>
                    </div>
 
                </div>
            </transition>
        </div>

2.给html加对应的css:

.selectBox{
    width: 200px;
    height: 26px;
    position: relative;
 
    .icon{
        position: absolute;
        right: 10px;
        top:10px;
        color:#C0C4CC;
        transition: all 0.5s;
        font-size: 14px;
 
        &.arrowtop{
            transition: all 0.5s;
            transform: rotate(-180deg);
        }
    }
 
    .dropdown{
        position: absolute;
        top:40px;
        z-index: 999;
        min-width: 200px;
        background: #fff;
        border: 1px solid #E4E7ED;
        border-radius: 4px;
        box-shadow: 0 2px 12px 0 rgba(0,0,0,0.1);
        -webkit-box-sizing: border-box;
        box-sizing: border-box;
        padding: 8px 0 2px;
 
        .el-select-dropdown .el-scrollbar {padding-bottom: 17px;}
        .contentMore{
            width: 200px;
            height:250px;
        }
        ul{
            box-sizing: border-box;
            display: block;
            margin-bottom: 12px;
 
            li{
                font-size: 14px;
                position: relative;
                white-space: nowrap;
                padding: 5px 16px;
                overflow: hidden;
                text-overflow: ellipsis;
                color: #606266;
                height: 34px;
                line-height: 26px;
                -webkit-box-sizing: border-box;
                box-sizing: border-box;
                cursor: pointer;
                text-align: left;
 
                &:hover{
                    background: #F5F7FA;
                }
                &.selected{
                    color: #0062B2;
                    font-weight: 700;
                }
            }
        }
 
        .arrow{
            position: absolute;
            top: -6px;
            left: 35px;
            margin-right: 3px;
            border-bottom-color: #EBEEF5;
            border-width: 6px;
            -webkit-filter: drop-shadow(0 2px 12px rgba(0, 0, 0, .03));
            filter: drop-shadow(0 2px 12px rgba(0, 0, 0, .03));
 
            &:after{
                content: " ";
                border-width: 6px;
                position: absolute;
                display: block;
                width: 0;
                height: 0;
                border-color: transparent;
                border-style: solid;
 
                top: 1px;
                margin-left: -6px;
                border-top-width: 0;
                border-bottom-color: #FFF;
            }
        }
    }
 
    input{
        -webkit-appearance: none;
        width: 100%;
        height:100%;
        border:1px solid #DCDFE6;
        outline: 0;
        border-radius: 2px;
        text-indent: 16px;
        transition: all 0.5s;
        cursor: pointer;
        /*background: #F5F7FA;*/
        color: #606266;
        font-size: 12px;
        background: rgba(255,255,255,0.1);
 
        &:hover{
            border:1px solid #C0C4CC;
        }
        &:focus{
            border:1px solid #0062B2;
        }
        &:active{
            border:1px solid #C0C4CC;
        }
        &:visited{
            border:1px solid #0062B2;
        }
 
        input::-webkit-input-placeholder{
            color:#C0C4CC;
        }
        input::-moz-placeholder{   /* Mozilla Firefox 19+ */
            color:#C0C4CC;
        }
        input:-moz-placeholder{    /* Mozilla Firefox 4 to 18 */
            color:#C0C4CC;
        }
        input:-ms-input-placeholder{  /* Internet Explorer 10-11 */
            color:#C0C4CC;
        }
    }

3.对应的js:

//获取焦点打开
            showdropbox(){
                this.$refs.searchInput.setAttribute("placeholder",JSON.parse(JSON.stringify(this.selectData.storeName)));
                this.selectData ={};
                this.showdrop = true;
                this.changeSelect = false; //未选择值
                this.loadPage.currentPage = 1;
                this.storeidlist = JSON.parse(JSON.stringify(this.storeidlistall.slice(0,this.loadPage.pageSize)));
 
 
            },
            //元素外的点击()替代离焦事件,解决点击选择冲突
            handleClose(){
 
                setTimeout(()=>{
                    //console.log('外外外外外外');
                    this.showdrop = false;
                    if( !this.changeSelect ){
                        this.selectData =JSON.parse(JSON.stringify(this.SelectValue));
                    }
 
                },50);
            },
            //失去焦点
            closedropbox(){
                /*setTimeout(()=>{
                    console.log('失去焦点')
                    this.showdrop = false;
                    if( !this.changeSelect ){
                        this.selectData =JSON.parse(JSON.stringify(this.SelectValue));
                    }
 
                },250);*/
            },
            //点击选择并关闭下拉
            selectOne(one){
                console.log('选择');
                this.selectData = JSON.parse(JSON.stringify(one));
                this.showdrop = false;
                this.changeSelect = true; //已选择值
 
                setTimeout(()=>{
                    this.SelectValue = JSON.parse(JSON.stringify(this.selectData));
 
                    this.$emit('changedata',JSON.parse(JSON.stringify(this.selectData)).storeId);
                },10)
            },
            //输入的值
            selectInput(val){
               //console.log('搜索',val,this.$refs.searchInput.value);
               //this.loadTextBox = false;
                if(this.$refs.searchInput.value){
                    this.storeidlist = [];
                    this.storeidlist = this.storeidlistall.filter((one)=>{
                        if(one.storeName.indexOf(this.$refs.searchInput.value)>-1 || String(one.externalStoreId).indexOf(this.$refs.searchInput.value)>-1){
                            return true;
                        }
                    });
                    let total = this.storeidlistall.length;
                    this.loadPage.currentPage = Math.ceil(total/this.loadPage.pageSize) ; //页码大于最大值则无需滚动加载
                }else{
                    this.loadPage.currentPage = 1;
                    this.storeidlist = JSON.parse(JSON.stringify(this.storeidlistall.slice(0,this.loadPage.pageSize)));
                }
                /*setTimeout(()=>{
                    this.loadTextBox = true; //解决滚动条不会跟着内容变化的问题
                },100);*/
 
            },
            //分页请求load
            load () {
                console.log('load');
 
                let total = this.storeidlistall.length;
                if(total/this.loadPage.pageSize<this.loadPage.currentPage){
                    return;
                }
                console.log(total/this.loadPage.pageSize,this.loadPage.currentPage);
 
                this.loadPage.currentPage++;
                this.storeidlist = [... this.storeidlist,...JSON.parse(JSON.stringify(
                    this.storeidlistall.slice((this.loadPage.currentPage-1)*this.loadPage.pageSize,
                        this.loadPage.currentPage*this.loadPage.pageSize )))];
 
            }

以上就是放element-ui制作的升级版,下拉搜索+分页滚动的组件啦:

基于vue和element-ui的搜索下拉滚动条组件_搜索_03

🚀写在最后

如果本文中有bug、逻辑错误,或者您有更好的优化方案欢迎评论联系我哦!~关注我持续分享日常工作中的组件设计和学习分享,一起进步加油!

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
hr26MWkbkYWR