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

如何阻止Vuetify中v-hover触发自定义函数

解决Vue中Hover时函数重复调用的问题

Hey there! Let's break down why your getMovieGenre function keeps triggering every time you hover over the card, and fix it for good.

Why this is happening

Template expressions like {{ getMovieGenre(movie.genres) }} run every time your component re-renders. When you use v-hover, the hover state changes on mouse enter/exit, which triggers a re-render of the component. That means your function gets called over and over again—wasting performance and causing unnecessary computations.

Fixes you can implement (from best to easiest)

1. Preprocess your movie data (Recommended)

The cleanest approach is to calculate the formatted genre string once when you load your movie data, instead of calculating it on every render. You can do this in a lifecycle hook like created or right after fetching your movies:

// Inside your component's script
created() {
  // Assuming your movies are stored in a reactive property
  this.movies = this.movies.map(movie => ({
    ...movie,
    // Compute the genre string once and store it
    formattedGenres: this.getMovieGenre(movie.genres)
  }))
}

// Then in your template, just use the precomputed property
<v-card-subtitle>{{ movie.formattedGenres }}</v-card-subtitle>

Now, no matter how many times the component re-renders (from hover or other changes), you're just referencing a precomputed string—no function calls needed.

2. Use a computed property

If your movie list is reactive (e.g., it might update after the component loads), a computed property is a great choice. Computed properties cache their results, so they only re-run when their dependencies change (not on every re-render):

// Inside your component's script
computed: {
  processedMovies() {
    return this.movies.map(movie => ({
      ...movie,
      formattedGenres: this.getMovieGenre(movie.genres)
    }))
  }
}

Then in your template, loop over processedMovies instead of the original movies array. This way, the genre strings are only recalculated if the movies array itself changes.

3. Memoize the function (Last resort)

If you absolutely have to call the function directly in the template, you can add memoization to it. Memoization caches the result of the function based on its input, so it won't re-run with the same genres value:

You can use Lodash's memoize utility, or write a simple version yourself:

// Using Lodash
import _ from 'lodash'

export default {
  methods: {
    getMovieGenre: _.memoize(function(genres) {
      // Your existing logic here (e.g., filter and join genres)
      return genres.filter(genre => genre.isActive).join(', ')
    })
  }
}

// Or a simple custom memoizer
export default {
  methods: {
    getMovieGenre(genres) {
      if (!this.genreCache) this.genreCache = {}
      const key = JSON.stringify(genres)
      if (!this.genreCache[key]) {
        this.genreCache[key] = genres.filter(genre => genre.isActive).join(', ')
      }
      return this.genreCache[key]
    }
  }
}

Note: This still calls the function on every render, but it skips the actual computation if the input hasn't changed. It's not as efficient as preprocessing, but it works if you can't modify the movie data upfront.


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 14:22:44