You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vuetify3中含hover触发菜单时其他v-menu无法正常关闭的问题

Vuetify 3 混合 hover/点击触发 v-menu 时的关闭异常修复

问题现象

在Vuetify 3中同时使用open-on-hover触发的v-menu和点击触发的v-menu时,会出现以下异常:

  • 点击按钮打开点击型菜单
  • 悬停文本框触发hover型菜单
  • 点击文本框后,点击型菜单仍保持打开状态

问题原因

hover型菜单的Overlay处于DOM层级最上层,点击文本框时,只会触发最上层hover菜单的关闭逻辑,下方的点击型菜单无法检测到外部点击事件,因此不会自动关闭。

修复方案

方案1:给hover菜单添加close-on-click属性

这是最简易的修复方式,给hover触发的v-menu添加close-on-click后,点击文本框时会先关闭hover菜单,此时点击事件会穿透到下方,触发点击型菜单的外部点击检测,从而自动关闭。

修改后的代码:

<template>
  <v-app>
    <v-container>
      <!-- 点击触发的菜单 -->
      <v-btn color="primary">
        Action Button
        <v-menu activator="parent"> Action menu </v-menu>
      </v-btn>

      <!-- 悬停触发的菜单 -->
      <v-text-field
        v-model="msg"
        style="margin-top: 20px"
      >
        <v-menu activator="parent" :open-on-hover="true" close-on-click>
          Text field messages
        </v-menu>
      </v-text-field>
    </v-container>
  </v-app>
</template>

<script setup>
import { ref } from 'vue'

const msg = ref('')
</script>

方案2:手动控制菜单显示状态

如果需要hover菜单保持打开(不希望点击关闭),可以通过绑定每个菜单的v-model,手动控制所有菜单的关闭逻辑:

<template>
  <v-app>
    <v-container>
      <v-btn color="primary">
        Action Button
        <v-menu activator="parent" v-model="actionMenuOpen"> Action menu </v-menu>
      </v-btn>

      <v-text-field
        v-model="msg"
        style="margin-top: 20px"
        @click="closeAllMenus"
      >
        <v-menu activator="parent" :open-on-hover="true" v-model="hoverMenuOpen">
          Text field messages
        </v-menu>
      </v-text-field>
    </v-container>
  </v-app>
</template>

<script setup>
import { ref, onMounted, onUnmounted } from 'vue'

const msg = ref('')
const actionMenuOpen = ref(false)
const hoverMenuOpen = ref(false)

// 关闭所有菜单
const closeAllMenus = () => {
  actionMenuOpen.value = false
  hoverMenuOpen.value = false
}

// 监听全局点击,点击非菜单区域时关闭所有菜单
const handleGlobalClick = (e) => {
  const isMenuRelated = e.target.closest('.v-menu__activator, .v-menu__content')
  if (!isMenuRelated) closeAllMenus()
}

onMounted(() => window.addEventListener('click', handleGlobalClick))
onUnmounted(() => window.removeEventListener('click', handleGlobalClick))
</script>

方案3:移除hover菜单的Overlay

如果hover菜单不需要全屏遮罩层,可以添加no-overlay属性,这样点击文本框时,点击事件会直接触发点击型菜单的外部点击检测:

<v-menu activator="parent" :open-on-hover="true" no-overlay>
  Text field messages
</v-menu>

内容的提问来源于stack exchange,提问作者Yu yuki

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 05:54:52