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

VueJS中单个商品项Hover仅显示自身价格的问题

问题解决:Vue循环项悬停时仅显示当前商品价格

问题原因

你当前使用了一个全局的hover布尔变量,所有循环渲染的<li>都绑定这个变量。鼠标悬停任意商品时,hover被设为true,导致所有商品的价格同时显示;鼠标离开时hover设为false,所有价格又同时隐藏。

解决方案

方案1:给每个商品单独维护hover状态

在加载Firebase数据时,给每个商品对象添加响应式的isHover属性,让每个商品的悬停状态独立可控。

修改后的script代码:

import { ref, onMounted } from 'vue'
import { collection, onSnapshot } from 'firebase/firestore'
import { db } from '@/firebase/config' // 替换为你的Firebase配置路径

setup() {
  const products = ref([])

  onMounted(() => {
    onSnapshot(collection(db, "malesneakers"), (querySnapshot) => {
      const maleProducts = []
      querySnapshot.forEach((doc) => {
        const mlproducts = {
          id: doc.id,
          imageSrc: doc.data().imageSrc,
          name: doc.data().name,
          price: doc.data().price,
          cheapestat: doc.data().cheapestat,
          svgSrc: doc.data().svgSrc,
          href: doc.data().href,
          isHover: ref(false) // 给每个商品添加独立的响应式悬停状态
        }
        maleProducts.push(mlproducts)
      })
      products.value = maleProducts
    })
  })

  return { products }
}

修改模板中的事件绑定和显示判断:

<div class="relative w-full pb-6 -mb-6 overflow-x-auto scrollbar-hide">
  <ul role="list" class="mx-4 inline-flex space-x-0  gap-2 sm:mx-6 lg:mx-0 lg:space-x-0 lg:grid lg:grid-cols-6 lg:gap-x-4">
    <li v-if="products.length" v-for="product in products" :key="product.id" 
        @mouseenter="product.isHover = true" @mouseleave="product.isHover = false"
        class="w-44 inline-flex  border hover:border-black rounded-lg p-4  lg:w-auto">
      <div class="group relative">
        <div class="w-[70%] lg:w-[55%] bg-gray-white overflow-hidden">
          <img :src="product.imageSrc" :alt="product.imageAlt" class="w-full h-20 overflow-hidden object-center object-contain" />
        </div>
        <div class="mt-2">
          <h3 class="mt-1 font-rubikreg h-11 overflow-hidden text-xs lg:text-base uppercase text-gray-900">
            <a :href="product.href">
              <span class="absolute inset-0" />
              {{ product.name }}
            </a>
          </h3>
         
          <p class="mt-3 lg:mt-6 font-rubiklight uppercase text-xs lg:text-sm text-gray-900">
            Cheapest At
          </p>
          <p class="mt-1 font-rubikreg underline-offset-2 underline uppercase text-xs lg:text-sm text-gray-900">
            {{ product.cheapestat }}
          </p>
      
          <p v-if="product.isHover" class="mt-5 text-2xl uppercase font-rubik text-gray-900">
            <span class="text-xs">From</span>
           A${{ product.price }}
          </p>
          
        </div>
      </div>
    </li>
  </ul>
</div>

方案2:维护当前悬停的商品ID

通过一个变量存储当前悬停商品的ID,模板中判断当前商品ID是否匹配该变量,从而控制价格显示。

修改后的script代码:

import { ref, onMounted } from 'vue'
import { collection, onSnapshot } from 'firebase/firestore'
import { db } from '@/firebase/config'

setup() {
  const products = ref([])
  const hoveredProductId = ref(null) // 存储当前悬停商品的ID

  onMounted(() => {
    onSnapshot(collection(db, "malesneakers"), (querySnapshot) => {
      const maleProducts = []
      querySnapshot.forEach((doc) => {
        const mlproducts = {
          id: doc.id,
          imageSrc: doc.data().imageSrc,
          name: doc.data().name,
          price: doc.data().price,
          cheapestat: doc.data().cheapestat,
          svgSrc: doc.data().svgSrc,
          href: doc.data().href,
        }
        maleProducts.push(mlproducts)
      })
      products.value = maleProducts
    })
  })

  return { products, hoveredProductId }
}

修改模板中的事件绑定和显示判断:

<div class="relative w-full pb-6 -mb-6 overflow-x-auto scrollbar-hide">
  <ul role="list" class="mx-4 inline-flex space-x-0  gap-2 sm:mx-6 lg:mx-0 lg:space-x-0 lg:grid lg:grid-cols-6 lg:gap-x-4">
    <li v-if="products.length" v-for="product in products" :key="product.id" 
        @mouseenter="hoveredProductId = product.id" @mouseleave="hoveredProductId = null"
        class="w-44 inline-flex  border hover:border-black rounded-lg p-4  lg:w-auto">
      <div class="group relative">
        <div class="w-[70%] lg:w-[55%] bg-gray-white overflow-hidden">
          <img :src="product.imageSrc" :alt="product.imageAlt" class="w-full h-20 overflow-hidden object-center object-contain" />
        </div>
        <div class="mt-2">
          <h3 class="mt-1 font-rubikreg h-11 overflow-hidden text-xs lg:text-base uppercase text-gray-900">
            <a :href="product.href">
              <span class="absolute inset-0" />
              {{ product.name }}
            </a>
          </h3>
         
          <p class="mt-3 lg:mt-6 font-rubiklight uppercase text-xs lg:text-sm text-gray-900">
            Cheapest At
          </p>
          <p class="mt-1 font-rubikreg underline-offset-2 underline uppercase text-xs lg:text-sm text-gray-900">
            {{ product.cheapestat }}
          </p>
      
          <p v-if="hoveredProductId === product.id" class="mt-5 text-2xl uppercase font-rubik text-gray-900">
            <span class="text-xs">From</span>
           A${{ product.price }}
          </p>
          
        </div>
      </div>
    </li>
  </ul>
</div>

说明

方案2更轻量,无需修改商品数据结构;方案1将状态与商品绑定,逻辑更独立,适合复杂场景,可根据需求选择。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 04:32:08