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

Vue.js菜单鼠标悬停时如何实现单个菜单项独立响应?

导航菜单项独立响应鼠标悬停的修复方案

当前导航菜单鼠标悬停时所有菜单项会同时切换默认图和悬停动图,需要调整代码让每个菜单项独立响应悬停事件。

用户原代码:

<template>
  <div class="container-lg">
    <nav>
      <ul class="nav justify-content-center">
        <li class="nav-item" v-for="link in menuLinks" :key="link.id"><a class="nav-link" :href=link.name @mouseover="moveGif" @mouseout="removeGif"><img :src=link.srcDflt v-if="dflt" class="w-75"/><img :src=link.srcHov v-if="hov" class="w-75"/></a></li>
      </ul>
    </nav>
  </div>
</template>

<script>
export default {
  data: () => ({
    dflt: true,
    hov: false,
    menuLinks: [
      {id: 1, name: 'random', srcDflt: require('../assets/Dice.png'), srcHov: require('../assets/gifs/Dice.gif')},
      {id: 2, name: 'index', srcDflt: require('../assets/Search.png'), srcHov: require('../assets/gifs/Search.gif')},
      {id: 3, name: 'editorial', srcDflt: require('../assets/Editorial.png'), srcHov: require('../assets/gifs/Editorial.gif')},
      {id: 4, name: 'favourites', srcDflt: require('../assets/Favourites.png'), srcHov: require('../assets/gifs/Favourites.gif')},
      {id: 5, name: 'aboutus', srcDflt: require('../assets/AboutUs.png'), srcHov: require('../assets/gifs/AboutUs.gif')},
      {id: 6, name: 'user', srcDflt: require('../assets/User.png'), srcHov: require('../assets/gifs/UserGif.gif')}
    ]
  }),
  methods: {
    moveGif: function() {
      this.dflt = false
      this.hov = true
    },
    removeGif: function() {
      this.dflt = true
      this.hov = false
    }
  }
}
</script>

问题原因

全局的dflt和hov状态会同时控制所有菜单项的显示/隐藏,导致悬停时所有项一起切换。需要给每个菜单项单独维护悬停状态。

修改步骤

  1. 更新menuLinks数据结构
    给每个菜单项添加isHover字段,初始为false,用来标记当前项是否处于悬停状态:
menuLinks: [
  {id: 1, name: 'random', srcDflt: require('../assets/Dice.png'), srcHov: require('../assets/gifs/Dice.gif'), isHover: false},
  {id: 2, name: 'index', srcDflt: require('../assets/Search.png'), srcHov: require('../assets/gifs/Search.gif'), isHover: false},
  {id: 3, name: 'editorial', srcDflt: require('../assets/Editorial.png'), srcHov: require('../assets/gifs/Editorial.gif'), isHover: false},
  {id: 4, name: 'favourites', srcDflt: require('../assets/Favourites.png'), srcHov: require('../assets/gifs/Favourites.gif'), isHover: false},
  {id: 5, name: 'aboutus', srcDflt: require('../assets/AboutUs.png'), srcHov: require('../assets/gifs/AboutUs.gif'), isHover: false},
  {id: 6, name: 'user', srcDflt: require('../assets/User.png'), srcHov: require('../assets/gifs/UserGif.gif'), isHover: false}
]
  1. 修改模板中的条件判断
    将全局的dflt/hov替换为当前项的isHover状态,同时给事件方法传递当前项的id:
<li class="nav-item" v-for="link in menuLinks" :key="link.id">
  <a class="nav-link" :href="link.name" @mouseover="moveGif(link.id)" @mouseout="removeGif(link.id)">
    <img :src="link.srcDflt" v-if="!link.isHover" class="w-75"/>
    <img :src="link.srcHov" v-if="link.isHover" class="w-75"/>
  </a>
</li>
  1. 调整方法逻辑
    通过菜单项的id找到对应项,单独修改它的isHover状态:
methods: {
  moveGif(id) {
    const targetLink = this.menuLinks.find(item => item.id === id)
    if (targetLink) targetLink.isHover = true
  },
  removeGif(id) {
    const targetLink = this.menuLinks.find(item => item.id === id)
    if (targetLink) targetLink.isHover = false
  }
}
  1. 移除全局状态
    删除data中的dflt和hov变量,因为不再需要:
data: () => ({
  menuLinks: [/* 保持更新后的数组内容 */]
})

可选优化方案

如果不想修改数据结构,也可以通过CSS实现悬停切换(更简洁):

  • 把默认图和悬停图放在同一个容器里,用CSS的:hover控制显示:
<li class="nav-item" v-for="link in menuLinks" :key="link.id">
  <a class="nav-link" :href="link.name">
    <div class="menu-img-container">
      <img :src="link.srcDflt" class="w-75 default-img"/>
      <img :src="link.srcHov" class="w-75 hover-img"/>
    </div>
  </a>
</li>

添加CSS:

.menu-img-container {
  position: relative;
}
.hover-img {
  position: absolute;
  top: 0;
  left: 0;
  opacity: 0;
  transition: opacity 0.2s;
}
.nav-link:hover .hover-img {
  opacity: 1;
}
.nav-link:hover .default-img {
  opacity: 0;
}

这种方式不需要JavaScript逻辑,纯CSS实现,性能更好也更易维护。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 17:35:19