封装element ui 下拉搜索带列表

话不多说,先上效果图

 这里是将它变成一个组件去使用,可以多个页面引入使用

一.模板界面部分


<!-- :style="{'width':_width,'height':_height}" -->
<template>
    <div class="about">
        <el-select ref="select" v-model="selectVal" :disabled="disabled" :placeholder="placeholders" size="mini" 
            :style="{ width: widths }" @blur="clearData" clearable  @visible-change="visibleChange" @clear="clearSelect">
            <!-- // 设置一个input框用作模糊搜索选项功能 -->
            <el-input v-model="keyWordFilter" class="input" placeholder="此处键入'关键词'搜索查询" prefix-icon="el-icon-search"
                 @input="handleInput" @clear="clear" clearable :validate-event="false"></el-input>
            <!-- // 设置一个隐藏的下拉选项,选项显示的是汉字label,值是value //
        如果不设置一个下拉选项,下面的树形组件将无法正常使用 -->
            <el-option key="id" hidden :value="selectVal" :label="selectVal">
            </el-option>
            <div ref="container" class="down">
                <ul ref="list">
                    <li class="liFlex" v-for="(item, index) in searchList" :key="index" @click.stop="handleSearchList(item)"
                        :style="{ background: isActive(item) ? '#f5f7fa' : '#fff' }">
                        <span>{{ item.number }}</span> <i v-if="isActive(item)" class="el-icon-check right-icon"></i>
                    </li>
                    <li v-show="searchResult" style="text-align: center">暂无搜索结果</li>
                    <li v-if="loading" style="text-align: center">加载中...</li>
                </ul>
            </div>
            <!-- <div v-show="searchResult">暂无搜索结果</div> -->
        </el-select>
    </div>
</template>
<script>
import { getBelong } from "@/api/ctm/ctm-add";
import { getServiceNumber } from "@/api/admin/sys-user";
export default {
    name: "Dorpdown",
    props: {
        url: {
            type: String,
            default: () => null,
        },
        widths: {
            type: String,
            default: () => null,
        },
        disabled: {
            type: Boolean,
            default: () => false,
        },
        placeholders: {
            type: String,
            default: () => null,
        },
        value: {
            type: [String, Number, Object],
            default: null
        },
    },
    data () {
        return {
            selectVal: "", // select框的绑定值
            selectName: "", // select框显示的name
            keyWordFilter: "", // 搜索框绑定值,用作过滤
            solist: [], // 搜索存储列表
            searchList: [], // 接口返回搜索
            loading: false,
            // 查询参数
            queryParams: {
                pageIndex: 1,
                pageSize: 10,
                keyword: "",
            },
            // 总条数
            total: 0,
            searchResult: false,
            timer: null,
            selectVal2: ''
        };
    },
    watch: {
        keyWordFilter: {
            handler (v) {
                if (!v) {
                    this.searchResult = false;
                    this.searchList = [];
                }
            },
        },
        value: {
            // 父组件使用选择的值回显给子组件
            immediate: true,
            handler (newValue) {
                this.selectVal = newValue;
            }
        },
        searchResult (n) {
            console.log(n);
        },
    },
    mounted () {
        this.$nextTick(() => {
            this.scrollToBottom();
        });
    },
    beforeDestroy () {
        // 移除滚动事件监听
        window.removeEventListener("scroll", this.handleScroll, true);
    },
    methods: {
        isActive (item) {
            return this.selectVal === item.number; // 这里的判断条件可以根据具体情况来定
        },
        scrollToBottom () {
            const container = this.$refs.container;
            const list = this.$refs.list;
            // 滚动到底部
            list.scrollTop = container.offsetHeight - list.offsetHeight;
            // 监听滚动事件
            list.addEventListener("scroll", this.handleScroll);
        },
        handleScroll () {
            const container = this.$refs.container;
            const list = this.$refs.list;
            // 判断是否滚动到底部
            if (
                list.scrollTop >=
                container.offsetHeight - 60 // 在底部前10像素进行判断,可根据需要调整
            ) {
                console.log(list.offsetHeight, "list.offsetHeight");
                // 在这里执行滚动到底部后的逻辑
                // console.log(this.searchList.length, "this.searchList.length");
                if (this.searchList.length < this.total) {
                    this.queryParams.pageIndex++;
                    this.search();
                }
            }
        },
        clearData () {
            this.keyWordFilter = "";
            this.queryParams.pageIndex = 1;
        },
        visibleChange (e) {
            if (!e) {
                this.searchList = [];
                this.clearData();
            } else {
                this.search();
            }
        },
        // 根据关键字搜索
        handleInput () {
            if (this.timer) {
                clearTimeout(this.timer);
            }
            this.timer = setTimeout(() => {
                this.searchList = [];
                this.queryParams.pageIndex = 1;
                this.queryParams.pageSize = 30;
                this.search();
            }, 300);
        },
        // 模拟搜索防抖
        async search () {
            this.queryParams.keyword = this.keyWordFilter;

            this.loading = true;
            let res;
            if (this.url === "addCtm") {
                res = await getBelong(this.queryParams);
            } else {
                res = await getServiceNumber(this.queryParams);
            }
            if (res.code === 200) {
                console.log(res.data.list, 'res.data.list');
                this.searchList = [...this.searchList, ...res.data.list];
                const map = new Map();
                const uniqueList = this.searchList.reduce((acc, item) => {
                    if (!map.has(item.userId)) {
                        map.set(item.userId, true);
                        acc.push(item);
                    }
                    return acc;
                }, []);
                this.searchList = uniqueList
                this.loading = false;
                console.log(this.searchList, "dorpdown");
                if (this.searchList.length === 0) {
                    this.searchResult = true;
                } else {
                    this.searchResult = false;
                }
                this.total = res.data.count;
            }
        },
        // 搜索框图标清空
        clear () {
            this.searchList = [];
            this.queryParams.pageIndex = 1;
            this.queryParams.pageSize = 20;
        },
        //   搜索列表点击
        handleSearchList (item) {
            this.selectVal = item.number;
            // this.selectVal=item.userId
            item.jobNumber = item.number;
            this.selectVal2 = item;
            this.$emit("modelClass", this.selectVal2);
            // this.$emit('input', this.selectVal);
            this.visibleChange();
            this.$refs.select.blur();
        },

        //   清空值v-model的select值
        clearSelect () {
            this.selectVal = "";
            this.selectVal2 = ''
            this.$emit("modelClass", this.selectVal2);
        },
        // 这个给父组件调用,因为上面那个有emit,父组件使用$refs来访问的时候会报错,不是一个方法
        newClearSelect () {
            this.selectVal = "";
            this.selectVal2 = ''
        }
    },
};
</script>
<style lang="scss" scoped>
::v-deep .el-scrollbar__bar {
    overflow-x: hidden;
}

::v-deep .el-input--mini .el-input__inner {
    height: 32px;
}

.input {
    width: 278px;
    margin: 10px;
}

.down {
    width: 298px;
    max-height: 160px;

    ul {
        width: 298px;
        max-height: 160px;
        overflow-y: scroll;
        margin: 0;
        padding: 0 12px;
        list-style: none;

        &::-webkit-scrollbar {
            /*滚动条整体样式*/
            width: 8px;
            /*高宽分别对应横竖滚动条的尺寸*/
            height: 1px;
        }

        &::-webkit-scrollbar-thumb {
            /*滚动条里面小方块*/
            border-radius: 10px;
            background: #cccccc;
            box-shadow: inset 0 0 5px #cccccc;
        }

        //滚动条底层颜色!
        &::-webkit-scrollbar-track {
            border-radius: 10px;
            background: #fdf8f5;

            /*滚动条里面轨道*/
            box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.1);
        }

        li {
            overflow: hidden; // 溢出隐藏
            white-space: nowrap; // 强制一行
            text-overflow: ellipsis; // 文字溢出显示省略号
            cursor: pointer;
            color: #606266;
            padding: 4px 0;

            &:hover {
                // color: rgb(0, 81, 255);
                background: #f5f7fa;
            }
        }
        .liFlex{
            display: flex;
            justify-content: space-between;
        }
    }
}
</style>

页面引入

import dorpdown from "../component/dorpdown.vue";

<el-col :span="6">
   <el-form-item label="归属工号" prop="belong">
  <!-- :placeholders="belong" -->
      <dorpdown ref="childDown" :widths="widths" :disabled="disableds" :url="'addCtm'"
     :value="diaForms.number" @modelClass="changeModelClass">
     </dorpdown>
   </el-form-item>
  </el-col>



  // 工号下拉搜索选择事件
        changeModelClass (e) {
            this.diaForms.belong = e.number;
            this.selectUserId = e.userId;
        },

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值