fix: 修复搜索菜单列表滚动 BUG (#105)
This commit is contained in:
parent
e32e3226d6
commit
f12f33014e
@ -26,9 +26,11 @@ const inputRef = ref<HTMLInputElement | null>(null)
|
|||||||
const scrollbarRef = ref<InstanceType<typeof ElScrollbar> | null>(null)
|
const scrollbarRef = ref<InstanceType<typeof ElScrollbar> | null>(null)
|
||||||
const searchResultRef = ref<InstanceType<typeof SearchResult> | null>(null)
|
const searchResultRef = ref<InstanceType<typeof SearchResult> | null>(null)
|
||||||
|
|
||||||
const keyword = ref("")
|
const keyword = ref<string>("")
|
||||||
const resultList = shallowRef<RouteRecordRaw[]>([])
|
const resultList = shallowRef<RouteRecordRaw[]>([])
|
||||||
const activeRouteName = ref<RouteRecordName>("")
|
const activeRouteName = ref<RouteRecordName>("")
|
||||||
|
/** 是否按下了上键或下键(用于解决和 mouseenter 事件的冲突) */
|
||||||
|
const isPressUpOrDown = ref<boolean>(false)
|
||||||
|
|
||||||
/** 控制搜索对话框宽度 */
|
/** 控制搜索对话框宽度 */
|
||||||
const modalWidth = computed(() => (appStore.device === DeviceEnum.Mobile ? "80vw" : "40vw"))
|
const modalWidth = computed(() => (appStore.device === DeviceEnum.Mobile ? "80vw" : "40vw"))
|
||||||
@ -76,13 +78,15 @@ const handleClose = () => {
|
|||||||
|
|
||||||
/** 根据下标位置进行滚动 */
|
/** 根据下标位置进行滚动 */
|
||||||
const scrollTo = (index: number) => {
|
const scrollTo = (index: number) => {
|
||||||
const scrollTop = searchResultRef.value?.getScrollTop(index)
|
if (!searchResultRef.value) return
|
||||||
|
const scrollTop = searchResultRef.value.getScrollTop(index)
|
||||||
// 手动控制 el-scrollbar 滚动条滚动,设置滚动条到顶部的距离
|
// 手动控制 el-scrollbar 滚动条滚动,设置滚动条到顶部的距离
|
||||||
scrollTop && scrollbarRef.value?.setScrollTop(scrollTop)
|
scrollbarRef.value?.setScrollTop(scrollTop)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 键盘上键 */
|
/** 键盘上键 */
|
||||||
const handleUp = () => {
|
const handleUp = () => {
|
||||||
|
isPressUpOrDown.value = true
|
||||||
const { length } = resultList.value
|
const { length } = resultList.value
|
||||||
if (length === 0) return
|
if (length === 0) return
|
||||||
const index = resultList.value.findIndex((item) => item.name === activeRouteName.value)
|
const index = resultList.value.findIndex((item) => item.name === activeRouteName.value)
|
||||||
@ -98,6 +102,7 @@ const handleUp = () => {
|
|||||||
|
|
||||||
/** 键盘下键 */
|
/** 键盘下键 */
|
||||||
const handleDown = () => {
|
const handleDown = () => {
|
||||||
|
isPressUpOrDown.value = true
|
||||||
const { length } = resultList.value
|
const { length } = resultList.value
|
||||||
if (length === 0) return
|
if (length === 0) return
|
||||||
const index = resultList.value.findIndex((item) => item.name === activeRouteName.value)
|
const index = resultList.value.findIndex((item) => item.name === activeRouteName.value)
|
||||||
@ -118,6 +123,11 @@ const handleEnter = () => {
|
|||||||
router.push({ name: activeRouteName.value })
|
router.push({ name: activeRouteName.value })
|
||||||
handleClose()
|
handleClose()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 释放上键或下键 */
|
||||||
|
const handleReleaseUpOrDown = () => {
|
||||||
|
isPressUpOrDown.value = false
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@ -128,6 +138,7 @@ const handleEnter = () => {
|
|||||||
@keydown.up="handleUp"
|
@keydown.up="handleUp"
|
||||||
@keydown.down="handleDown"
|
@keydown.down="handleDown"
|
||||||
@keydown.enter="handleEnter"
|
@keydown.enter="handleEnter"
|
||||||
|
@keyup.up.down="handleReleaseUpOrDown"
|
||||||
:before-close="handleClose"
|
:before-close="handleClose"
|
||||||
:width="modalWidth"
|
:width="modalWidth"
|
||||||
top="5vh"
|
top="5vh"
|
||||||
@ -142,8 +153,14 @@ const handleEnter = () => {
|
|||||||
<el-empty v-if="resultList.length === 0" description="暂无搜索结果" :image-size="100" />
|
<el-empty v-if="resultList.length === 0" description="暂无搜索结果" :image-size="100" />
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<p>搜索结果</p>
|
<p>搜索结果</p>
|
||||||
<el-scrollbar ref="scrollbarRef" max-height="40vh">
|
<el-scrollbar ref="scrollbarRef" max-height="40vh" always>
|
||||||
<SearchResult ref="searchResultRef" v-model="activeRouteName" :list="resultList" @click="handleEnter" />
|
<SearchResult
|
||||||
|
ref="searchResultRef"
|
||||||
|
v-model="activeRouteName"
|
||||||
|
:list="resultList"
|
||||||
|
:isPressUpOrDown="isPressUpOrDown"
|
||||||
|
@click="handleEnter"
|
||||||
|
/>
|
||||||
</el-scrollbar>
|
</el-scrollbar>
|
||||||
</template>
|
</template>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
|
@ -5,6 +5,7 @@ import { type RouteRecordName, type RouteRecordRaw } from "vue-router"
|
|||||||
interface Props {
|
interface Props {
|
||||||
modelValue: RouteRecordName
|
modelValue: RouteRecordName
|
||||||
list: RouteRecordRaw[]
|
list: RouteRecordRaw[]
|
||||||
|
isPressUpOrDown: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = defineProps<Props>()
|
const props = defineProps<Props>()
|
||||||
@ -36,6 +37,8 @@ const itemStyle = (item: RouteRecordRaw) => {
|
|||||||
|
|
||||||
/** 鼠标移入 */
|
/** 鼠标移入 */
|
||||||
const handleMouseenter = (item: RouteRecordRaw) => {
|
const handleMouseenter = (item: RouteRecordRaw) => {
|
||||||
|
// 如果上键或下键与 mouseenter 事件同时生效,则以上下键为准,不执行该函数的赋值逻辑
|
||||||
|
if (props.isPressUpOrDown) return
|
||||||
activeRouteName.value = item.name!
|
activeRouteName.value = item.name!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user