2023-12-07 10:03:31 +08:00
|
|
|
|
<template>
|
2024-05-23 16:00:40 +08:00
|
|
|
|
<div class="HintInfo" id="myHint" @mouseenter="onMouseenter">
|
2023-12-14 16:20:33 +08:00
|
|
|
|
<ul style="padding-left: 0;margin: -10px 0 0 0;min-width: calc(100% - 12px)">
|
2023-12-07 10:03:31 +08:00
|
|
|
|
<template v-for="(item,index) in hintList" :key="index">
|
|
|
|
|
|
<li :ref="'hint_'+index" class="relative-item CodeMirror-hint"
|
2023-12-15 18:48:51 +08:00
|
|
|
|
style="margin-bottom: 2px"
|
2023-12-07 10:03:31 +08:00
|
|
|
|
@click="handleSelect(item,index,hintList)"
|
2024-05-23 16:00:40 +08:00
|
|
|
|
:id="'filterItem'+index"
|
2023-12-07 10:03:31 +08:00
|
|
|
|
:class="{'CodeMirror-hint-active':index === activeIndex,[item.className]:true}"
|
|
|
|
|
|
>{{ item.displayText }}</li>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
</ul>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<script>
|
|
|
|
|
|
export default {
|
|
|
|
|
|
name: 'HintInfo',
|
|
|
|
|
|
props: {
|
|
|
|
|
|
hintList: {
|
|
|
|
|
|
type: Array,
|
|
|
|
|
|
default () {
|
|
|
|
|
|
return []
|
|
|
|
|
|
}
|
2024-06-04 18:06:00 +08:00
|
|
|
|
},
|
|
|
|
|
|
columnList: {
|
|
|
|
|
|
type: Array
|
2023-12-07 10:03:31 +08:00
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
data () {
|
|
|
|
|
|
return {
|
|
|
|
|
|
active: true,
|
2024-05-23 16:00:40 +08:00
|
|
|
|
activeIndex: null,
|
|
|
|
|
|
currentIndex: -1
|
2023-12-07 10:03:31 +08:00
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
mounted () {
|
|
|
|
|
|
// this.handleFocus()
|
|
|
|
|
|
this.$emit('load', {
|
|
|
|
|
|
name: this.name,
|
|
|
|
|
|
label: this.name,
|
|
|
|
|
|
vm: this
|
|
|
|
|
|
})
|
2024-05-23 16:00:40 +08:00
|
|
|
|
document.addEventListener('keydown', this.initKeyDown)
|
2023-12-07 10:03:31 +08:00
|
|
|
|
},
|
|
|
|
|
|
methods: {
|
2024-05-23 16:00:40 +08:00
|
|
|
|
initKeyDown (event) {
|
|
|
|
|
|
const dom = document.getElementById('myHint')
|
|
|
|
|
|
const vm = this
|
|
|
|
|
|
if (dom) {
|
|
|
|
|
|
// 检测方向键
|
|
|
|
|
|
switch (event.key) {
|
|
|
|
|
|
case 'Enter':
|
|
|
|
|
|
// eslint-disable-next-line no-case-declarations
|
|
|
|
|
|
const item = vm.hintList[vm.currentIndex]
|
|
|
|
|
|
if (item) {
|
|
|
|
|
|
this.$emit('keydownEnter', 'Enter')
|
2024-06-04 18:06:00 +08:00
|
|
|
|
const obj = vm.columnList.find(d => d.label === item.displayText)
|
|
|
|
|
|
// 如果选中label,数组更新,光标处在第一行。如果选择操作符,光标位置不变
|
|
|
|
|
|
if (obj) {
|
|
|
|
|
|
vm.handleSelect(item, vm.currentIndex, vm.hintList)
|
|
|
|
|
|
const itemDom = document.getElementById('filterItem' + vm.currentIndex)
|
|
|
|
|
|
if (itemDom) {
|
|
|
|
|
|
itemDom.style.backgroundColor = ''
|
|
|
|
|
|
}
|
|
|
|
|
|
vm.$nextTick(() => {
|
|
|
|
|
|
vm.currentIndex = 1
|
|
|
|
|
|
const itemDom1 = document.getElementById('filterItem1')
|
|
|
|
|
|
if (itemDom1) {
|
|
|
|
|
|
itemDom1.style.backgroundColor = 'var(--el-fill-color-dark)'
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
} else {
|
|
|
|
|
|
vm.handleSelect(item, vm.currentIndex, vm.hintList)
|
|
|
|
|
|
}
|
2024-05-23 16:00:40 +08:00
|
|
|
|
} else {
|
|
|
|
|
|
this.$emit('keydownEnter', null)
|
|
|
|
|
|
}
|
|
|
|
|
|
break
|
|
|
|
|
|
case 'ArrowUp': // 上方向键
|
|
|
|
|
|
// 上方向键被按下时的操作
|
|
|
|
|
|
if ((vm.currentIndex <= vm.hintList.length - 1) && vm.currentIndex > 0) {
|
|
|
|
|
|
vm.currentIndex -= 1
|
|
|
|
|
|
} else {
|
|
|
|
|
|
vm.currentIndex = vm.hintList.length - 1
|
|
|
|
|
|
}
|
|
|
|
|
|
vm.hintList.forEach((e, index) => {
|
|
|
|
|
|
if (index === vm.currentIndex) {
|
|
|
|
|
|
let realIndex = index
|
|
|
|
|
|
if (e.type === 'abstract') {
|
|
|
|
|
|
realIndex -= 1
|
|
|
|
|
|
vm.currentIndex -= 1
|
|
|
|
|
|
}
|
|
|
|
|
|
const itemDom = document.getElementById('filterItem' + realIndex)
|
|
|
|
|
|
if (itemDom) {
|
|
|
|
|
|
itemDom.style.backgroundColor = 'var(--el-fill-color-dark)'
|
2024-06-04 18:06:00 +08:00
|
|
|
|
itemDom.scrollIntoView(false)
|
2024-05-23 16:00:40 +08:00
|
|
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
|
|
const itemDom = document.getElementById('filterItem' + index)
|
|
|
|
|
|
if (itemDom) {
|
|
|
|
|
|
itemDom.style.backgroundColor = ''
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
break
|
|
|
|
|
|
case 'ArrowDown': // 下方向键
|
|
|
|
|
|
if (vm.currentIndex < vm.hintList.length - 1) {
|
|
|
|
|
|
vm.currentIndex += 1
|
|
|
|
|
|
} else {
|
|
|
|
|
|
vm.currentIndex = 0
|
|
|
|
|
|
}
|
|
|
|
|
|
vm.hintList.forEach((e, index) => {
|
|
|
|
|
|
if (index === vm.currentIndex) {
|
|
|
|
|
|
let realIndex = index
|
|
|
|
|
|
if (e.type === 'abstract') {
|
|
|
|
|
|
realIndex += 1
|
|
|
|
|
|
vm.currentIndex += 1
|
|
|
|
|
|
}
|
|
|
|
|
|
const itemDom = document.getElementById('filterItem' + realIndex)
|
|
|
|
|
|
if (itemDom) {
|
|
|
|
|
|
itemDom.style.backgroundColor = 'var(--el-fill-color-dark)'
|
2024-06-04 18:06:00 +08:00
|
|
|
|
itemDom.scrollIntoView(false)
|
2024-05-23 16:00:40 +08:00
|
|
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
|
|
const itemDom = document.getElementById('filterItem' + index)
|
|
|
|
|
|
if (itemDom) {
|
|
|
|
|
|
itemDom.style.backgroundColor = ''
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
break
|
|
|
|
|
|
default:
|
|
|
|
|
|
// 其他按键的操作
|
|
|
|
|
|
break
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
2023-12-07 10:03:31 +08:00
|
|
|
|
scrollToView (index = 0) {
|
|
|
|
|
|
// 移动到可视区域
|
|
|
|
|
|
const li = this.$refs['hint_' + index][0]
|
|
|
|
|
|
li && li.scrollIntoView(false)
|
|
|
|
|
|
},
|
|
|
|
|
|
handleDown () {
|
|
|
|
|
|
if (!this.active) {
|
|
|
|
|
|
this.hintActive()
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
let nextIndex = this.activeIndex + 1
|
|
|
|
|
|
let nextItem = this.hintList[nextIndex]
|
|
|
|
|
|
|
|
|
|
|
|
if (nextItem?.type === 'abstract') {
|
|
|
|
|
|
nextIndex++
|
|
|
|
|
|
nextItem = this.hintList[nextIndex]
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (nextItem?.type === 'abstract') {
|
|
|
|
|
|
nextIndex++
|
|
|
|
|
|
}
|
|
|
|
|
|
nextIndex >= this.hintList.length ? this.activeIndex = 1 : this.activeIndex = nextIndex
|
|
|
|
|
|
this.scrollToView(this.activeIndex)
|
|
|
|
|
|
},
|
|
|
|
|
|
handleUp () {
|
|
|
|
|
|
if (!this.active) {
|
|
|
|
|
|
this.hintActive()
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
let preIndex = this.activeIndex - 1
|
|
|
|
|
|
let preItem = this.hintList[preIndex]
|
|
|
|
|
|
|
|
|
|
|
|
if (preItem?.type === 'abstract') {
|
|
|
|
|
|
preIndex--
|
|
|
|
|
|
preItem = this.hintList[preIndex]
|
|
|
|
|
|
}
|
|
|
|
|
|
if (preItem?.type === 'abstract') {
|
|
|
|
|
|
preIndex--
|
|
|
|
|
|
}
|
|
|
|
|
|
preIndex > 0 ? this.activeIndex = preIndex : this.activeIndex = this.hintList.length - 1
|
|
|
|
|
|
this.scrollToView(this.activeIndex)
|
|
|
|
|
|
},
|
|
|
|
|
|
hintActive () {
|
|
|
|
|
|
this.active = true
|
|
|
|
|
|
this.activeIndex = 1
|
|
|
|
|
|
this.scrollToView(this.activeIndex)
|
|
|
|
|
|
},
|
|
|
|
|
|
hintDeactive () {
|
|
|
|
|
|
this.active = false
|
|
|
|
|
|
this.activeIndex = null
|
|
|
|
|
|
},
|
|
|
|
|
|
handleSelect (item, index) {
|
|
|
|
|
|
this.$emit('select', item, index, this.hintList)
|
|
|
|
|
|
},
|
|
|
|
|
|
triggerSelect () {
|
|
|
|
|
|
const index = this.activeIndex || 0
|
|
|
|
|
|
const item = this.hintList[index]
|
|
|
|
|
|
this.$emit('select', item, index, this.hintList)
|
2024-05-23 16:00:40 +08:00
|
|
|
|
},
|
|
|
|
|
|
onMouseenter () {
|
|
|
|
|
|
const itemDom = document.getElementById('filterItem' + this.currentIndex)
|
|
|
|
|
|
if (itemDom) {
|
|
|
|
|
|
itemDom.style.backgroundColor = ''
|
|
|
|
|
|
this.currentIndex = -1
|
|
|
|
|
|
}
|
2023-12-07 10:03:31 +08:00
|
|
|
|
}
|
2024-05-23 16:00:40 +08:00
|
|
|
|
},
|
|
|
|
|
|
unmounted () {
|
|
|
|
|
|
document.removeEventListener('keydown', this.initKeyDown)
|
2023-12-07 10:03:31 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
</script>
|