el-select可搜索,可根据字母检索

一,自定义的el-select可查询可根据字母进行筛选类似联系人列表

<template>
    <el-select v-model="selectedProvince" filterable remote :remote-method="queryProvinces" placeholder="请选择省份"
        clearable @visible-change="visibleChange" @visible="handleVisible" class="custom-select "
        :popper-append-to-body='false'>
        <div class="alphabet-column">
            <div v-for="letter in letters" :key="letter" @click="scrollToProvince(letter)">
                {{ letter }}
            </div>
        </div>
        <el-option-group v-for="(group, index) in sortedProvinceGroups" :key="index" :label="group.letter">
            <el-option v-for="province in group.provinces" :key="province.id" :label="province.name"
                :value="province.id" :ref="`provinceOption-${province.id}`"></el-option>
        </el-option-group>

    </el-select>
</template>
<script>
export default {
    data() {
        return {
            selectedProvince: '', // 绑定选中的省份
            selectedLetter: '',
            provinces: [],
            letters: ['A', 'B', 'C', 'F', 'G', 'H', 'J', 'L', 'N', 'Q', 'S', 'T', 'X', 'Y', 'Z'] // 字母数组
        };
    },
    mounted() {
        this.provinces = [
            { id: 1, name: '北京', letter: 'B' },
            { id: 2, name: '天津', letter: 'T' },
            { id: 3, name: '河北', letter: 'H' },
            { id: 4, name: '山西', letter: 'S' },
            { id: 5, name: '内蒙古', letter: 'N' },
            { id: 6, name: '辽宁', letter: 'L' },
            { id: 7, name: '吉林', letter: 'J' },
            { id: 8, name: '黑龙江', letter: 'H' },
            { id: 9, name: '上海', letter: 'S' },
            { id: 10, name: '江苏', letter: 'J' },
            { id: 11, name: '浙江', letter: 'Z' },
            { id: 12, name: '安徽', letter: 'A' },
            { id: 13, name: '福建', letter: 'F' },
            { id: 14, name: '江西', letter: 'J' },
            { id: 15, name: '山东', letter: 'S' },
            { id: 16, name: '河南', letter: 'H' },
            { id: 17, name: '湖北', letter: 'H' },
            { id: 18, name: '湖南', letter: 'H' },
            { id: 19, name: '广东', letter: 'G' },
            { id: 20, name: '广西', letter: 'G' },
            { id: 21, name: '海南', letter: 'H' },
            { id: 22, name: '重庆', letter: 'C' },
            { id: 23, name: '四川', letter: 'S' },
            { id: 24, name: '贵州', letter: 'G' },
            { id: 25, name: '云南', letter: 'Y' },
            { id: 26, name: '西藏', letter: 'X' },
            { id: 27, name: '陕西', letter: 'S' },
            { id: 28, name: '甘肃', letter: 'G' },
            { id: 29, name: '青海', letter: 'Q' },
            { id: 30, name: '宁夏', letter: 'N' },
            { id: 31, name: '新疆', letter: 'X' },
            { id: 32, name: '台湾', letter: 'T' },
            { id: 33, name: '香港', letter: 'X' },
            { id: 34, name: '澳门', letter: 'A' }
        ]
    },
    computed: {
        sortedProvinceGroups() {
            // 如果没有选择字母,则返回所有省份分组
            if (!this.selectedLetter) {
                // 根据首字母对省份数据进行分组和排序
                const sortedProvinces = this.provinces.sort((a, b) => a.letter.localeCompare(b.letter));
                const groups = {};
                sortedProvinces.forEach(province => {
                    const letter = province.letter;
                    if (!groups[letter]) {
                        groups[letter] = [];
                    }
                    groups[letter].push(province);
                });
                return Object.keys(groups).map(letter => ({ letter, provinces: groups[letter] }));
            }

            // 只返回选定字母对应的省份组
            return this.provinces
                .filter(province => province.letter === this.selectedLetter)
                .map(province => ({ letter: province.letter, provinces: [province] }));
        }
    },
    methods: {
        // 点击字母滚动到对应省份位置
        scrollToProvince(letter) {
            this.selectedLetter = letter;
            console.log(letter)
            const targetProvince = this.provinces.find(province => province.letter === letter);
            if (targetProvince) {
                const targetRef = this.$refs[`provinceOption-${targetProvince.id}`]; // 获取对应的 ref
                if (targetRef) {
                    console.log(targetRef, 'ref')
                    targetRef.$el.scrollIntoView();
                }
            }
        },
        // 远程搜索函数
        queryProvinces(query) {
            // 模拟异步请求,实际中应该发送请求到后端进行检索
            setTimeout(() => {
                // 根据输入内容查询匹配的省份
                const matchedProvinces = this.provinces.filter(province => province.name.includes(query));
                // 将查询结果传递给 el-select 组件
                this.provinces = matchedProvinces;
            }, 300); // 模拟延迟
        },
        // 处理下拉框显示事件
        handleVisible(visible) {
            if (visible) {
                // 下拉框显示时,滚动到第一个省份
                this.$nextTick(() => {
                    const firstProvince = this.provinces[0];
                    if (firstProvince) {
                        const targetRef = this.$refs[`provinceOption-${firstProvince.id}`]; // 获取对应的 ref
                        if (targetRef) {
                            targetRef.$el.scrollIntoView();
                        }
                    }
                });
            }
        },
        // 处理下拉框显示/隐藏变化事件
        visibleChange(visible) {
            if (!visible) {
                // 下拉框隐藏时,重置搜索条件
                // 这里你可以根据需要进行其他操作,比如清空搜索框内容等
                this.selectedLetter = "";
            }
        }

    }
};
</script>
<style scoped>
.custom-select .el-input__inner {

    padding-right: 30px;
    /* 增加右侧间距 */
}

.alphabet-column {
    display: flex;
    flex-direction: column;
    position: absolute;
    right: 5px;
    /* 调整位置 */
    top: 0;
    bottom: 0;
    padding-top: 10px;
    /* 调整上下内边距 */
    pointer-events: none;
    /* 不影响下拉框的点击事件 */
    z-index: 1;
    /* 设置 z-index,确保在选项之上 */
    font-size: 10px;

}

.alphabet-column div {
    cursor: pointer;
    margin-bottom: 5px;
    pointer-events: auto;
    /* 恢复点击事件 */
}

/deep/.el-select-dropdown__wrap {
    min-height: 280px !important;
    text-align: start;
}

/* 调整选项的样式,确保不遮挡右侧字母列 */
.el-select-dropdown .el-scrollbar__wrap {
    overflow: visible !important;
}

.el-select-dropdown .el-option {
    overflow: visible !important;
}

.el-select-dropdown .el-option__content {
    overflow: visible !important;
}

.el-select-dropdown .el-option__content:hover {
    background-color: transparent !important;
    /* 鼠标悬停时取消背景色 */
}
</style>

  • 5
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值