123 lines
2.9 KiB
Vue

<template>
<div class="dropdown-menu">
<div class="dropdown-menu-list" v-if="items?.length">
<div
class="dropdown-item"
:class="{ 'is-selected': index === selectedIndex }"
v-for="(item, index) in varList"
:key="index"
@click="selectItem(index)"
>
<div class="label"> {{ item.text }}</div>
<span class="value">{{item.value}}</span>
</div>
</div>
<div class="not-exists" v-else>
<span>数据指标不存在</span>
</div>
</div>
</template>
<script setup lang="ts">
import {getProductValue} from "@/service/use-result-vars.js";
import {watch, ref} from "vue";
const productList = getProductValue();
const varList = ref<ResultVarItem[] >([])
const props = defineProps({
items: {
type: Array,
},
query:{
type: String,
},
command: {
type: Function,
required: true,
},
});
const selectedIndex = ref(0)
watch(()=>props.query, () => {
selectedIndex.value = 0;
if(props.query){
const q = String(props.query)
varList.value = productList.value.filter(item => (
item.value.includes(q) || item.label.includes(q) || (item.text && item.text.includes(q))
));//.filter((_,index)=> index < 10)
}else{
varList.value = productList.value.filter((_,index)=> index < 10)
}
});
const upHandler = () => {
selectedIndex.value = ((selectedIndex.value + varList.value.length) - 1) % varList.value.length
}
const downHandler = () => {
selectedIndex.value = (selectedIndex.value + 1) % varList.value.length
}
const enterHandler = () => {
selectItem(selectedIndex.value)
}
const selectItem = (index:number) => {
const item = varList.value[index]
if (item) {
props.command({id: item.value, label: item.text || item.label})
}
// selectedIndex.value = index
}
const onKeyDown = ({event}: { event: { key: string } }) => {
if (event.key === 'ArrowUp') {
upHandler()
return true
}
if (event.key === 'ArrowDown') {
downHandler()
return true
}
if (event.key === 'Enter') {
enterHandler()
return true
}
return false
}
defineExpose({onKeyDown})
</script>
<style lang="scss">
/* Dropdown menu */
.dropdown-menu-list{
}
.dropdown-menu {
@apply bg-white relative overflow-auto flex flex-col shadow rounded border border-gray-200;
max-height: calc(100vh - 300px);
}
.dropdown-item {
@apply w-full p-2 gap-2 bg-transparent flex items-center cursor-pointer justify-between;
text-align: left;
&:hover,
&:hover.is-selected {
@apply bg-gray-200;
}
&.is-selected {
@apply bg-gray-100;
}
.label{
@apply text-gray-800;
}
.value{
@apply text-gray-300 text-sm;
}
}
.not-exists {
@apply p-2;
}
</style>