组件:
<template>
<a-select
placeholder="请选择"
:mode="selectType === 'check' ? 'multiple' : 'default'"
:value="value"
:options="formattedOptions"
:open="isOpen"
@click="handleSelectClick"
@change="handleChange"
show-search
:field-names="fieldName"
>
<template v-if="value.includes('其他')" #dropdownRender="{ menuNode: menu }">
<v-nodes :vnodes="menu" />
<div
style="width: 100%;display: flex;justify-content: space-around;margin: 5px 0px;align-items: center;"
>
<a-input class="input23" v-model:value="inputValue" style="width: 50%" />
<a-button size="small" class="input23" @click.stop="submit" type="primary">确定</a-button>
</div>
</template>
</a-select>
</template>
<script setup>
import { getCurrentInstance, onMounted, onUnmounted, ref, computed } from 'vue';
const { emit } = getCurrentInstance();
const isOpen = ref(false);
// eslint-disable-next-line no-undef
const props = defineProps({
options: {
type: Array,
required: true
},
value: {
type: [Array,String],
required: false,
default: () => []
},
selectType: {
type: String,
required: false,
default: () => 'single'
},
valueType: {
type: String,
required: false,
default: () => 'list'
},
fieldName: {
type: Object,
required: false,
}
});
const inputValue = ref('');
const formattedOptions = computed(() => {
if (props.valueType === 'obj') {
return props.options;
} else {
return props.options.map(option => ({ label: option, value: option }));
}
});
function submit() {
isOpen.value = false;
if (props.selectType === 'check') {
const index = props.value.findIndex(item => item === '其他')
let list = [...props.value]
if (index !== -1) {
list.splice(index, 1)
}
emit('update:value', [...list, inputValue.value])
}
else emit('update:value', inputValue.value)
}
const VNodes = (_, { attrs }) => {
return attrs.vnodes;
};
function handleChange(val,) {
isOpen.value = val.includes('其他') || props.selectType === 'check' ;
emit('update:value', val);
}
function handleSelectClick() {
if (isOpen.value) return;
if (!isOpen.value) {
isOpen.value = true
return;
}
if (!props.value.includes('其他')) {
isOpen.value = true;
}
}
const handleGlobalClick = (event) => {
const target = event.target;
const selectNode = target.closest('.ant-select-selector');
const optionNode = target.closest('.ant-select-item-option');
const optionNode2 = target.closest('.input23');
if (!optionNode2 && !selectNode && !optionNode && !props.value.includes('其他')) {
isOpen.value = false;
}
};
onMounted(() => {
document.addEventListener('click', handleGlobalClick);
});
onUnmounted(() => {
document.removeEventListener('click', handleGlobalClick);
});
</script>
其他页面使用:
1,单选:
<SelectOther v-model:value="data.formState.papersType" :options="data.papersType" style="width: 200px"/>
2,多选:
<SelectOther v-model:value=""
:options="data.chestSigns"
:select-type="'check'" //多选
style="margin: -5px 0;width: 120px"/>
3,二级下拉列表:
<SelectOther :value-type="'obj'" //二级列表数据
:field-name="{
label: 'name',
value: 'name',
options: 'child' }" //自定义二级数据格式
style="width: 100%"
v-model:value=""
:options="options.drugName"/>