优化菜单项的操作逻辑

This commit is contained in:
2024-12-12 22:18:38 +08:00
parent b7a939ee85
commit 8bf80c2f31

View File

@@ -48,6 +48,8 @@ const selectedMenuIndex = ref<number>(-1)
const toastVisible = ref<boolean>(false)
/** Toast 消息内容 */
const toastMessage = ref<string>('')
/** 是否正在使用键盘导航菜单 */
const isKeyboardNavigation = ref<boolean>(false)
// ===== 定时器 =====
/** 鼠标悬停禁用定时器 */
@@ -82,6 +84,8 @@ const showContextMenu = (data: { item: ListItem }): void => {
handleSelect(item)
showMenu.value = true
listFrozen.value = true
selectedMenuIndex.value = 0
isKeyboardNavigation.value = true
emit('context-menu', data)
}
@@ -92,6 +96,7 @@ const closeMenu = (): void => {
showMenu.value = false
listFrozen.value = false
selectedMenuIndex.value = -1
isKeyboardNavigation.value = false
// 临时禁用鼠标悬停,防止菜单关闭时立即触发悬停效果
temporaryDisableHover.value = true
@@ -128,6 +133,8 @@ const handleMenuTriggerClick = (e: MouseEvent): void => {
// 如果没有数据,仅显示菜单
showMenu.value = true
listFrozen.value = true
selectedMenuIndex.value = 0
isKeyboardNavigation.value = true
}
}
}
@@ -151,6 +158,7 @@ const handleKeyDown = (e: KeyboardEvent): void => {
switch (e.key) {
case 'ArrowUp':
e.preventDefault()
isKeyboardNavigation.value = true
// 向上选择菜单项,到顶部时循环到底部
selectedMenuIndex.value =
selectedMenuIndex.value <= 0
@@ -159,6 +167,7 @@ const handleKeyDown = (e: KeyboardEvent): void => {
break
case 'ArrowDown':
e.preventDefault()
isKeyboardNavigation.value = true
// 向下选择菜单项,到底部时循环到顶部
selectedMenuIndex.value =
selectedMenuIndex.value >= props.menuItems.length - 1
@@ -188,6 +197,11 @@ const showToast = (message: string): void => {
}, 3000)
}
// 添加鼠标悬浮处理函数
const handleMenuItemHover = (index: number): void => {
selectedMenuIndex.value = index
}
// ===== 生命周期钩子 =====
/**
* 组件挂载时添加全局事件监听
@@ -301,6 +315,7 @@ const onAfterLeave = (el: Element): void => {
class="menu-item"
:class="{ 'menu-item-selected': index === selectedMenuIndex }"
@click="handleMenuClick(item)"
@mouseover="handleMenuItemHover(index)"
>
{{ item.label }}
</div>
@@ -438,13 +453,6 @@ const onAfterLeave = (el: Element): void => {
font-weight: 400;
}
/* 菜单项悬停和选中状态 */
.menu-item:hover,
.menu-item-selected {
background-color: rgba(0, 0, 0, 0.04);
color: rgba(0, 0, 0, 0.87);
}
/* 选中项信息区域 */
.selected-item-info {
padding: 12px 16px;
@@ -555,4 +563,10 @@ const onAfterLeave = (el: Element): void => {
opacity: 0;
transform: translate(-50%, calc(-50% - 20px));
}
/* 统一的选中效果 */
.menu-item-selected {
background-color: rgba(0, 0, 0, 0.08);
color: rgba(0, 0, 0, 0.87);
}
</style>