web/src/components/PopoverInput.vue

101 lines
2.2 KiB
Vue

<template>
<el-popover placement="bottom-start" :visible="isVisible" :width="props.width" ref="popoverRef">
<template #reference>
<el-input v-model="input" style="width:100%;height: 100%" clearable :disabled="disabled" ref="inputRef" @click="showPopo" @focus="focus" @blur="handlerBlur"></el-input>
</template>
<div class="code-popo" v-if="props.list.length > 0">
<div class="code-item" v-for="item in props.list">
<div class="code-item-header" v-if="item.header">
{{item.header}}
</div>
<div class="code-item-name" v-for="subItem in item.value" @click="inputStr(subItem,item)">
{{ subItem }}
</div>
</div>
</div>
</el-popover>
</template>
<script setup lang="ts">
import {ref, unref} from "vue";
const isVisible = ref(false)
interface ListItem {
header?: string;
value: string[];
suffix?: string;
}
const input = defineModel<string | null>();
const props = defineProps({
list: {
type: Array as () => ListItem[],
default: []
},
width: {
type: Number,
default: 1000
},
disabled: {
type: Boolean,
default: false
}
})
const popoverRef = ref();
const showPopo = () => {
unref(popoverRef).popperRef?.delayHide?.()
}
const inputStr = (str: string,item:ListItem) => {
let strList = input.value ? input.value.split(",") : [];
if (item.suffix){
str = str + item.suffix;
}
strList.push(str);
input.value = strList.join(",");
}
const inputRef = ref();
const emit=defineEmits(["focus"])
const focus = () => {
isVisible.value = true
emit("focus", false)
}
const handlerBlur = () => {
isVisible.value = false
}
</script>
<style scoped lang="scss">
.code-popo {
width: 100%;
.code-item {
display: flex;
flex-wrap: wrap;
padding: 5px 0;
border-bottom: 1px solid #DDDDDD;
.code-item-header{
font-weight: bold;
color: #000;
font-size: 16px;
box-sizing: border-box;
padding: 5px;
text-align: center;
}
.code-item-name {
float: left;
font-size: 16px;
box-sizing: border-box;
padding: 5px;
text-align: center;
cursor: pointer;
&:hover {
color: #000;
}
&:after {
clear: both;
}
}
}
}
</style>