<template>
|
<div class="history-selector">
|
<label class="select-label">选择历史数据:</label>
|
<div class="custom-select">
|
<div class="select-value" @click="toggleDropdown">
|
<span v-if="!selectedItem">-- 选择历史数据 --</span>
|
<span v-else>{{ selectedItem.name }} - {{ selectedItem.goodsId }}</span>
|
<span class="select-arrow" :class="{ 'open': isDropdownOpen }"></span>
|
</div>
|
<ul class="select-dropdown" v-if="isDropdownOpen" @click.stop>
|
<li
|
class="select-option"
|
:class="{ 'selected': !selectedItem }"
|
@click="selectOption(null)"
|
>
|
-- 选择历史数据 --
|
</li>
|
<li
|
v-for="(item, index) in historyItems"
|
:key="index"
|
class="select-option"
|
:class="{ 'selected': selectedItem && selectedItem.goodsId === item.goodsId && selectedItem.bid === item.bid }"
|
@click="selectOption(item)"
|
>
|
{{ item.name }} - {{ item.goodsId }}
|
</li>
|
</ul>
|
</div>
|
</div>
|
</template>
|
|
<script setup lang="ts">
|
import {ref, watch} from 'vue';
|
import {BidFormData} from "/src-com";
|
|
interface Props {
|
historyItems: BidFormData[];
|
modelValue: BidFormData | null;
|
}
|
|
const props = defineProps<Props>();
|
const emit = defineEmits([
|
'update:modelValue',
|
'selected'
|
]);
|
|
const isDropdownOpen = ref(false);
|
const selectedItem = ref<BidFormData | null>(props.modelValue);
|
|
// 监听外部modelValue变化
|
watch(() => props.modelValue, (newValue) => {
|
selectedItem.value = newValue;
|
});
|
|
// 切换下拉菜单
|
const toggleDropdown = () => {
|
isDropdownOpen.value = !isDropdownOpen.value;
|
};
|
|
// 选择选项
|
const selectOption = (item: BidFormData | null) => {
|
selectedItem.value = item;
|
emit('update:modelValue', item);
|
emit('selected', item);
|
isDropdownOpen.value = false;
|
};
|
|
// 点击外部关闭下拉菜单
|
const handleClickOutside = (event: MouseEvent) => {
|
const selectElement = document.querySelector('.custom-select');
|
if (selectElement && !selectElement.contains(event.target as Node)) {
|
isDropdownOpen.value = false;
|
}
|
};
|
|
// 添加点击外部事件监听
|
document.addEventListener('click', handleClickOutside);
|
|
// 组件卸载时移除事件监听
|
defineExpose({
|
onUnmounted: () => {
|
document.removeEventListener('click', handleClickOutside);
|
}
|
});
|
</script>
|
|
<style scoped>
|
.history-selector {
|
margin-bottom: 20px;
|
}
|
|
.select-label {
|
display: block;
|
margin-bottom: 8px;
|
font-weight: 500;
|
}
|
|
.custom-select {
|
position: relative;
|
width: 100%;
|
max-width: 400px;
|
}
|
|
.select-value {
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
padding: 8px 12px;
|
background-color: #fff;
|
border: 1px solid #ddd;
|
border-radius: 4px;
|
cursor: pointer;
|
transition: border-color 0.3s;
|
}
|
|
.select-value:hover {
|
border-color: #666;
|
}
|
|
.select-arrow {
|
display: inline-block;
|
width: 0;
|
height: 0;
|
border-left: 5px solid transparent;
|
border-right: 5px solid transparent;
|
border-top: 5px solid #666;
|
transition: transform 0.3s;
|
}
|
|
.select-arrow.open {
|
transform: rotate(180deg);
|
}
|
|
.select-dropdown {
|
position: absolute;
|
top: 100%;
|
left: 0;
|
right: 0;
|
background-color: #fff;
|
border: 1px solid #ddd;
|
border-top: none;
|
border-radius: 0 0 4px 4px;
|
list-style: none;
|
margin: 0;
|
padding: 0;
|
max-height: 200px;
|
overflow-y: auto;
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
z-index: 10;
|
}
|
|
.select-option {
|
padding: 8px 12px;
|
cursor: pointer;
|
transition: background-color 0.2s;
|
}
|
|
.select-option:hover {
|
background-color: #f0f0f0;
|
}
|
|
.select-option.selected {
|
background-color: #e6f7ff;
|
color: #1890ff;
|
}
|
</style>
|