背景
antdv select 官方使用dropdownRender对下拉菜单进行自由扩展
效果展示
可添加,删除
代码
<template>
<div class="select-wrapper">
<a-select v-model="value"
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
:disabled="disabled"
>
<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="text" placeholder="请输入其他学历" allowClear @blur="addItem" />
</div>
</div>
<a-select-option v-for="(item,index) in items" :key="item" :value="item" :label="item">
{{ item }}
<a-icon v-if="index > 2" style="position: absolute;top:30%;right: 10%;" type="delete" @click.stop="deleteItem(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 {
props: {
value:{
type: String,
required: false
},
disabled:{
type: Boolean,
required: false,
default: false
},
},
components: {
VNodes: {
functional: true,
render: (h, ctx) => ctx.props.vnodes
}
},
data: () => ({
items: ['大学本科', '硕士研究生','博士研究生'],
// value: '',
open: false,
clickHandle: null,
text: '',
}),
methods: {
/**
* 删除分组选项
*/
deleteItem (label) {
const index = this.items.indexOf(label)
this.items.splice(index, 1)
},
addItem() {
this.items.push(this.text)
},
openSelect() {
this.open = !this.open
},
selectOption(value) {
// 单选时设置
this.$emit('change',value)
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>
<style scoped>
.select-wrapper {
position: relative;
.select_overlap {
cursor: pointer;
height: 32px;
width: 300px;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
opacity: 0;
}
}
</style>