antdv select下拉菜单自由扩展—添加输入框的使用问题

背景
antdv select 官方使用dropdownRender对下拉菜单进行自由扩展,
为了解决点击 dropdownRender 里的内容浮层关闭的问题,官方建议添加preventDefault,但是这样扩展内容里的输入框无法聚焦
在这里插入图片描述

一开始采取的方案是手动给自定义的输入框focus事件,但是基于页面只会有一个focus的原则,会因此触发select的输入框blur,反而导致下拉菜单收起,最后还是采取手动控制select的open属性来解决了问题

解决思路

  • 在select上添加一个透明的div作为select替身,只用来控制open,这样不用调用select组件的blur和focus,避免和原组件的处理有冲突
  • 选中选项(单选时)或者点击select控件外的地方操控open = false (dropdownRender处阻止冒泡stopPropagation,这样便于监听除下拉选项的全局事件)

实现效果
在这里插入图片描述

具体代码如下
selectInput.vue

<template>
    <div class="select-wrapper">
        <a-select default-value="lucy" 
            style="width: 300px" 
            dropdownClassName="dropdown-class-name" 
            placeholder="请选择" 
            :open="open" 
            @select="selectOption" 
            :class="{'ant-select-open': open}" 
            option-label-prop="label"
            :filter-option="filterOption"
            show-search
        >
            <div slot="dropdownRender" slot-scope="menu" @click="(e) => {e.stopPropagation()}">
                <v-nodes :vnodes="menu" />
                <a-divider style="margin: 4px 0" />
                <div style="padding: 4px 8px; cursor: pointer">
                    <a-input class="input-txt" v-model="value" placeholder="请输入" allowClear @pressEnter="addItem" />
                </div>
            </div>
            <a-select-option v-for="item in items" :key="item" :value="item" :label="item">
                {{ item }}
            </a-select-option>
        </a-select>
        <!--原来的,因为有遮罩的div导致不能使用自带的搜索和删除
        <div class="select_overlap" @mousedown="openSelect"></div>-->
        <!--最新方案,展开后隐藏遮罩即可使用组件本身的功能-->
        <div v-show="!open" class="select_overlap" @mouseup="openSelect"></div>
    </div>
</template>
<script>
export default {
    components: {
        VNodes: {
            functional: true,
            render: (h, ctx) => ctx.props.vnodes
        }
    },
    data: () => ({ items: ['jack', 'lucy'], value: '', open: false, clickHandle: null }),
    methods: {
        addItem() {
            this.items.push(this.value)
        },
        openSelect() {
            this.open = !this.open
        },
        selectOption() {
            // 单选时设置
            this.open = false
        },
        filterOption(input, option) {
            return option.componentOptions.propsData.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
        },
    },
    mounted() {
        this.clickHandle = (e) => {
            if (e.target && 'className' in e.target && this.open) {
                const className = e.target.className;
                if (className.indexOf('select_overlap') === -1) {
                    this.open = false
                }
            } else {
                this.open = false
            }
        }
        document.body.addEventListener('click', this.clickHandle)
    },
    beforeDestroy() {
        if (this.clickHandle) {
            document.body.removeEventListener('click', this.clickHandle)
            this.clickHandle = null
        }
    }
}
</script>

selectInput.less

.select-wrapper {
    position: relative;
    .select_overlap {
        cursor: pointer;
        height: 32px;
        width: 300px;
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        opacity: 0;
    }
}
  • 6
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 10
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值