鼠标悬停或悬浮在Vue.js中的应用

177
我想在vue.js中实现鼠标悬停在元素上时显示一个div,但似乎无法使其正常工作。 看起来在vue.js中没有hovermouseover事件,这是真的吗? 是否有可能结合jquery的hover方法和vue的方法来完成此功能?

2
v-on指令也可用于“hover”事件。如果您在问题中添加您编写的代码,我们可能会帮助您使其正常工作。是的,Vue很简单、小巧,旨在与其他包(如jQuery)集成。 - David K. Hess
15个回答

260

我觉得悬停的逻辑是错误的。它仅在鼠标悬停时才反转。我使用了以下代码,看起来完美无瑕。

<div @mouseover="upHere = true" @mouseleave="upHere = false" >
  <h2> Something Something </h2>
  <some-component v-show="upHere"></some-component>
</div>

关于Vue实例

data: {
  upHere: false
}

20
这应该是被采纳的答案!被采纳和得到最多赞同的答案会导致组件闪烁。每当鼠标移动到@mouseover-div上时,当前状态就会反转... - Stefan Medack
如果你展示一个隐藏的div,比如说一个气泡,当鼠标经过时会出现闪烁。只需要在隐藏的div上添加相同的鼠标经过/离开代码即可解决问题。 - mcmacerson
对我来说可以工作,只需使用webpack将您的数据更改为:data: () => ({ upHere: false }) - Emile Cantero
1
对于遇到当子元素悬停时出现闪烁问题的人,请使用 mouseenter 事件,而不是 mouseover。 - Sovetnikov

131

这是我认为你所要求的工作示例。

http://jsfiddle.net/1cekfnqw/3017/

 <div id="demo">
        <div v-show="active">Show</div>
        <div @mouseover="mouseOver">Hover over me!</div>
    </div>

var demo = new Vue({
    el: '#demo',
    data: {
        active: false
    },
    methods: {
        mouseOver: function(){
            this.active = !this.active;   
        }
    }
});

28
不支持最新的Vue版本。@CYB尝试编辑你的答案为v-on:mouseover="mouseOver",但没有指明在哪个Vue版本中语法发生了变化。 - Aprillion
3
@NICO提供的解决方案比我的更好,并且适用于当前版本(发布该帖子时的1.0.26版本)。请参考他的答案。谢谢。 - Jarrod
1
我想删除这个帖子,因为我刚刚说过,下面@NICO的帖子比我的更好,而且更加更新。请给NICO那个正确的答案,我会删除我的帖子。谢谢! - Jarrod
2
这个例子有问题吗? - user3743266
7
我认为最好使用缩写 @mouseover:mouseover - Davod Aslani Fakor

86

这里不需要一个方法。

HTML

<div v-if="active">
    <h2>Hello World!</h2>
 </div>

 <div v-on:mouseover="active = !active">
    <h1>Hover me!</h1>
 </div>

JavaScript

new Vue({
  el: 'body',
  data: {
    active: false
  }
})

11
你可以根据文档 http://vuejs.org/guide/syntax.html#v-on-Shorthand 使用 v-on:mouseover 或快捷方式 @mouseover - nu everest
1
你可以将 on 替换为 v-on:@,用于任何 HTML 事件属性。http://www.w3schools.com/tags/ref_eventattributes.asp - nu everest
什么问题?这个可以工作,应该标记为正确答案。 - NICO
Vue 2.2.0 不喜欢这样做 - 会抛出一个警告 "[Vue warn]: 不要将 Vue 挂载到 <html> 或 <body> 上 - 而是挂载到普通元素上。" - Dima Fomin
为了简单起见,我将<body>作为Vue实例。当然,在您的真实应用程序中不应该这样做。 - NICO

27

仅使用CSS可以显示子元素或同级元素。如果在组合器(+~>空格)之前使用 :hover,则样式不会应用于悬停的元素。

HTML

<body>
  <div class="trigger">
    Hover here.
  </div>
  <div class="hidden">
    This message shows up.
  </div>
</body>

CSS

.hidden { display: none; }
.trigger:hover + .hidden { display: inline; }

2
提问者特别询问了vue.js。因为它允许将JavaScript轻松绑定到mouseover事件。 - nu everest
7
我正在使用Vue,这对我来说是最好的解决方案。我有一个嵌套列表,其中包含只在鼠标悬停时才应出现的按钮,使用额外变量来跟踪悬停状态会过度复杂。CSS更加优雅。感谢qsc! - david_nash

19
使用 mouseovermouseleave 事件,可以定义一个切换函数,实现此逻辑并在渲染中对值进行响应。
检查此示例:

var vm = new Vue({
 el: '#app',
 data: {btn: 'primary'}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">


<div id='app'>
    <button
        @mouseover="btn='warning'"
        @mouseleave="btn='primary'"
        :class='"btn btn-block btn-"+btn'>
        {{ btn }}
    </button>
</div>


CSS后处理器(例如PurgeCSS)无法像这样动态构建类时捕获您的类。更好的方法是:@mouseover="btn-color='btn-warning' @mouseleave="btn-color='btn-primary' :class="btn btn-block { btn-color}" - Erich

13

我认为你想要实现的是通过结合以下两个方面来完成:

@mouseover, @mouseout, @mouseenter and @mouseleave

所以最佳的两种组合方式是:

"@mouseover and @mouseout"

或者
"@mouseenter and @mouseleave"

我认为,最好使用第二个,这样您可以实现悬停效果并在其上调用功能。

    <div @mouseenter="activeHover = true" @mouseleave="activeHover = false" >
        <p v-if="activeHover"> This will be showed on hover </p>
        <p v-if ="!activeHover"> This will be showed in simple cases </p>
    </div>    

在 Vue 实例上

    data : {
        activeHover : false
    }

注意:第一对会影响/传递给子元素,但第二对仅会影响您想要使用的位置而不是子元素。否则,使用第一对可能会导致某些故障/波动。因此,最好使用第二对以避免任何波动。

希望这也能帮助其他人 :)


10

我会使用新的组合 API 给出更新。

组件

<template>
  <div @mouseenter="hovering = true" @mouseleave="hovering = false">
    {{ hovering }}
  </div>
</template>

<script>
  import { ref } from '@vue/composition-api'

  export default {
    setup() {
      const hovering = ref(false)
      return { hovering }
    }
  })
</script>

可复用的组合函数

创建一个useHover函数将允许您在任何组件中重复使用。

export function useHover(target: Ref<HTMLElement | null>) {
  const hovering = ref(false)

  const enterHandler = () => (hovering.value = true)
  const leaveHandler = () => (hovering.value = false)

  onMounted(() => {
    if (!target.value) return
    target.value.addEventListener('mouseenter', enterHandler)
    target.value.addEventListener('mouseleave', leaveHandler)
  })

  onUnmounted(() => {
    if (!target.value) return
    target.value.removeEventListener('mouseenter', enterHandler)
    target.value.removeEventListener('mouseleave', leaveHandler)
  })

  return hovering
}

以下是在Vue组件内调用该函数的快速示例。

<template>
  <div ref="hoverRef">
    {{ hovering }}
  </div>
</template>

<script lang="ts">
  import { ref } from '@vue/composition-api'
  import { useHover } from './useHover'

  export default {
    setup() {
      const hoverRef = ref(null)
      const hovering = useHover(hoverRef)
      return { hovering, hoverRef }
    }
  })
</script>

你也可以使用类库,例如@vuehooks/core,其中包含许多有用的函数,包括useHover

参考文献:Vue.js 组合式 API


8

在组件模板中严格地悬停切换类是可能的,但出于明显的原因,这不是一个实用的解决方案。然而,对于原型设计,我发现无需在脚本中定义数据属性或事件处理程序很有用。

以下是使用Vuetify尝试调整图标颜色的示例。

new Vue({
  el: '#app'
})
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/vuetify/dist/vuetify.min.css" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify/dist/vuetify.js"></script>

<div id="app">
  <v-app>
    <v-toolbar color="black" dark>
      <v-toolbar-items>
        <v-btn icon>
          <v-icon @mouseenter="e => e.target.classList.toggle('pink--text')" @mouseleave="e => e.target.classList.toggle('pink--text')">delete</v-icon>
        </v-btn>
        <v-btn icon>
          <v-icon @mouseenter="e => e.target.classList.toggle('blue--text')" @mouseleave="e => e.target.classList.toggle('blue--text')">launch</v-icon>
        </v-btn>
        <v-btn icon>
          <v-icon @mouseenter="e => e.target.classList.toggle('green--text')" @mouseleave="e => e.target.classList.toggle('green--text')">check</v-icon>
        </v-btn>
      </v-toolbar-items>
    </v-toolbar>
  </v-app>
</div>


7

仅使用 mouseover 时,当鼠标离开被悬停元素后,元素会消失,因此我添加了以下内容:

@mouseover="active = !active" @mouseout="active = !active"

<script>
export default {
  data(){
   return {
     active: false
   }
 }
</script>

2
我遇到了同样的问题,但我解决了它!

        <img :src='book.images.small' v-on:mouseenter="hoverImg">


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接