在 Quasar 框架中,默认情况下 `menu` 是通过点击触发的(例如用于下拉菜单),但如果你希望它通过 hover 触发,可以通过以下方式实现。
实现方式:使用 v-model+ @mouseover和 @mouseleave
可以结合 Vue 的响应式变量和事件来控制 `` 的显隐状态。
示例代码(Vue3 + Quasar)
<template>
<div class="hover-menu">
<q-btn flat label="Hover Me">
<q-menu v-model:show="isMenuVisible" :offset="[0, 10]">
<q-list style="min-width: 150px">
<q-item clickable v-for="i in 3" :key="i">
<q-item-section>菜单项 {{ i }}</q-item-section>
</q-item>
</q-list>
</q-menu>
<!-- 鼠标进入/离开按钮时控制菜单 -->
@mouseover="() => isMenuVisible = true"
@mouseleave="() => isMenuVisible = false"
</q-btn>
</div>
</template>
<script setup>
import { ref } from 'vue'
const isMenuVisible = ref(false)
</script>
<style scoped>
.hover-menu {
padding: 20px;
}
</style>
补充说明
v-model:show | 控制菜单是否可见 |
@mouseover | 当鼠标进入按钮时打开菜单 |
@mouseleave | 当鼠标离开按钮时关闭菜单 |
进阶:支持延迟显示/隐藏(防止抖动)
使用 setTimeout 添加一个轻微的延迟,让菜单不会因为快速划过而频繁开关:
<script setup>
import { ref } from 'vue'
const isMenuVisible = ref(false)
let timer = null
function showMenu() {
timer = setTimeout(() => {
isMenuVisible.value = true
}, 150) // 延迟 150ms 显示
}
function hideMenu() {
clearTimeout(timer)
timer = setTimeout(() => {
isMenuVisible.value = false
}, 200) // 延迟 200ms 隐藏
}
</script>
template 中绑定事件:
<q-btn
flat
label="Hover Me"
@mouseover="showMenu"
@mouseleave="hideMenu"
>
<q-menu v-model:show="isMenuVisible" :offset="[0, 10]">
<q-list style="min-width: 150px">
<q-item clickable v-for="i in 3" :key="i">
<q-item-section>菜单项 {{ i }}</q-item-section>
</q-item>
</q-list>
</q-menu>
</q-btn>
更高级:支持 hover 菜单内容(带交互)
<template>
<div
class="hover-wrapper"
@mouseover="showMenu"
@mouseleave="hideMenu"
>
<q-btn flat label="Hover Me" />
<q-menu v-model:show="isMenuVisible" no-parent-event :offset="[0, 10]">
<q-list style="min-width: 150px">
<q-item clickable v-for="i in 3" :key="i">
<q-item-section>菜单项 {{ i }}</q-item-section>
</q-item>
</q-list>
</q-menu>
</div>
</template>
注意事项
no-parent-event | 如果你不加这个属性,菜单会阻止父级的 mouseleave |
样式隔离 | 推荐给容器加个class或ref来精确控制 |
支持动画 | 可以添加``实现淡入淡出效果 |
移动端兼容 | hover 在移动端不生效,需要额外处理 |