【问题标题】:Mouseover or hover vue.js鼠标悬停或悬停 vue.js
【发布时间】:2015-09-03 21:21:06
【问题描述】:

我想在 vue.js 中将鼠标悬停在一个元素上时显示一个 div。但我似乎无法让它工作。

vue.js 中似乎没有hovermouseover 的事件。这是真的吗?

可以结合jquery hover和vue方法吗?

【问题讨论】:

  • v-on 指令也适用于“悬停”事件。如果您将您编写的代码添加到您的问题中,我们可能会帮助您使其正常工作。是的,Vue 简单而小巧,旨在与 jQuery 等其他包集成。

标签: javascript vue.js hover mouseover


【解决方案1】:

我觉得上面的悬停逻辑是不正确的。它只是在鼠标悬停时反转。我用过下面的代码。它似乎工作得很好。

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

在 vue 实例上

data : {
    upHere : false
}

希望有帮助

【讨论】:

  • 这应该是公认的答案!接受和最受支持的答案确实会导致闪烁的组件。 @mouseover-div 上光标的每次移动都会反转当前状态...
  • 如果你显示一个隐藏的 div 像一个气泡,你会在鼠标悬停时闪烁。只需将相同的鼠标悬停/鼠标离开代码添加到隐藏的 div 即可。
  • 对我有用,使用 webpack 只需将您的数据更改为:data: () =&gt; ({ upHere: false })
  • 对于任何在孩子悬停时因闪烁而苦苦挣扎的人,请使用 mouseenter 事件而不是 mouseover
【解决方案2】:

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

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;   
        }
    }
});

【讨论】:

  • 不适用于最新的 vue 版本。 @CYB 尝试编辑您对 v-on:mouseover="mouseOver" 的回答,但没有提及语法更改的 vue 版本
  • @NICO 有比我更好的解决方案,并且适用于当前版本(在本文发布时为 1.0.26)。请参考他的回答。谢谢。
  • 我想删除这个,因为我刚才说过,@NICO 下面的帖子比我的好,而且更新。请给 NICO 正确答案,我会删除我的。谢谢!
  • 例子坏了?
  • 我认为最好使用速记@mouseover:mouseover
【解决方案3】:

这里不需要方法。

HTML

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

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

JS

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

【讨论】:

  • 您可以使用v-on:mouseover 或根据文档vuejs.org/guide/syntax.html#v-on-Shorthand 的快捷方式@mouseover
  • 对于任何 html 事件属性,您可以将 on 替换为 v-on:@w3schools.com/tags/ref_eventattributes.asp
  • 有什么问题?这个正在运行,应该标记为正确答案。
  • Vue 2.2.0 不喜欢这样 - 发出警告“[Vue warn]: 不要将 Vue 挂载到 或 - 改为挂载到普通元素。”
  • 为了简单起见,我将 做成了一个 vue 实例。当然,您不应该在现实世界的应用程序中这样做。
【解决方案4】:

要显示子元素或兄弟元素,只能使用 CSS。如果您在组合符之前使用:hover+~&gt;space)。然后样式不适用于悬停元素。

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; }

【讨论】:

  • 提问者特意询问vue.js。因为它允许 javascript 轻松绑定到 mouseover 事件。
  • 我正在使用 Vue,这对我来说是最好的解决方案。我有一个嵌套列表,其中包含只应出现在悬停时的按钮,并且使用额外的变量来跟踪悬停状态是矫枉过正的。 CSS 更加优雅。谢谢qsc!
【解决方案5】:

使用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}"
【解决方案6】:

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

这是一个如何使用 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, @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
        }
    

    注意:第 1 对 也会影响/移动子元素,但 第 2 对 只会影响您想要使用它的地方,而不是子元素。否则,使用 第一对 时您会遇到一些故障/波动。所以,最好使用第二对来避免任何波动。

    我希望,它也会对其他人有所帮助:)

    【讨论】:

      【解决方案8】:

      虽然我会使用新的组合 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

      参考:Vuejs composition API

      【讨论】:

        【解决方案9】:

        使用mouseover 只有当鼠标离开悬停元素时该元素仍然可见,所以我添加了这个:

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

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

        【讨论】:

          【解决方案10】:

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

                  &lt;img :src='book.images.small' v-on:mouseenter="hoverImg"&gt;

          【讨论】:

            【解决方案11】:

            有一个正确的工作 JSFiddle:http://jsfiddle.net/1cekfnqw/176/

            <p v-on:mouseover="mouseOver" v-bind:class="{on: active, 'off': !active}">Hover over me!</p>
            

            【讨论】:

              【解决方案12】:

              如果您不满意,请查看 vue-mouseover 包此代码的外观如何:

              <div
                  @mouseover="isMouseover = true"
                  @mouseleave="isMouseover = false"
              />
              

              vue-mouseover 提供了一个 v-mouseover 指令,当光标进入或离开该指令所附加的 HTML 元素时,该指令会自动更新指定的数据上下文属性。

              在下一个示例中,默认情况下,isMouseover 属性将在光标位于 HTML 元素上时为 true,否则为 false

              <div v-mouseover="isMouseover" />
              

              默认情况下isMouseover 将在v-mouseover 附加到div 元素时初始分配,因此在第一个mouseenter/mouseleave 事件之前它不会保持未分配状态.

              您可以通过v-mouseover-value 指令指定自定义值

              <div
                  v-mouseover="isMouseover"
                  v-mouseover-value="customMouseenterValue"/>
              

              <div
                  v-mouseover="isMouseover"
                  v-mouseover-value="{
                      mouseenter: customMouseenterValue,
                      mouseleave: customMouseleaveValue
                  }"
              />
              

              自定义默认值可以在设置过程中通过options object 传递给包。

              【讨论】:

                【解决方案13】:

                这是一个非常简单的 MouseOver 和 MouseOut 示例:

                <div id="app">
                   <div :style = "styleobj" @mouseover = "changebgcolor" @mouseout = "originalcolor"> 
                   </div>
                </div>
                
                new Vue({
                  el:"#app",
                  data:{
                     styleobj : {
                       width:"100px",
                       height:"100px",
                       backgroundColor:"red"
                     }
                  },
                  methods:{
                    changebgcolor : function() {
                      this.styleobj.backgroundColor = "green";
                    },
                    originalcolor : function() {
                      this.styleobj.backgroundColor = "red";
                    }
                  }
                });
                

                【讨论】:

                  【解决方案14】:

                  这对我有用 nuxt

                  <template>
                    <span
                      v-if="item"
                      class="primary-navigation-list-dropdown"
                      @mouseover="isTouchscreenDevice ? null : openDropdownMenu()"
                      @mouseleave="isTouchscreenDevice ? null : closeDropdownMenu()"
                    >
                      <nuxt-link
                        to="#"
                        @click.prevent.native="openDropdownMenu"
                        v-click-outside="closeDropdownMenu"
                        :title="item.title"
                        :class="[
                          item.cssClasses,
                          { show: isDropdownMenuVisible }
                        ]"
                        :id="`navbarDropdownMenuLink-${item.id}`"
                        :aria-expanded="[isDropdownMenuVisible ? true : false]"
                        class="
                          primary-navigation-list-dropdown__toggle
                          nav-link
                          dropdown-toggle"
                        aria-current="page"
                        role="button"
                        data-toggle="dropdown"
                      >
                        {{ item.label }}
                      </nuxt-link>
                      <ul
                        :class="{ show: isDropdownMenuVisible }"
                        :aria-labelledby="`navbarDropdownMenuLink-${item.id}`"
                        class="
                          primary-navigation-list-dropdown__menu
                          dropdown-menu-list
                          dropdown-menu"
                      >
                        <li
                          v-for="item in item.children" :key="item.id"
                          class="dropdown-menu-list__item"
                        >
                          <NavLink
                            :attributes="item"
                            class="dropdown-menu-list__link dropdown-item"
                          />
                        </li>
                      </ul>
                    </span>
                  </template>
                  
                  <script>
                  import NavLink from '@/components/Navigation/NavLink';
                  
                  export default {
                    name: "DropdownMenu",
                    props: {
                      item: {
                        type: Object,
                        required: true,
                      },
                    },
                    data() {
                      return {
                        isDropdownMenuVisible: false,
                        isTouchscreenDevice: false
                      };
                    },
                    mounted() {
                      this.detectTouchscreenDevice();
                    },
                    methods: {
                      openDropdownMenu() {
                        if (this.isTouchscreenDevice) {
                          this.isDropdownMenuVisible = !this.isDropdownMenuVisible;
                        } else {
                          this.isDropdownMenuVisible = true;
                        }
                      },
                  
                      closeDropdownMenu() {
                        if (this.isTouchscreenDevice) {
                          this.isDropdownMenuVisible = false;
                        } else {
                          this.isDropdownMenuVisible = false;
                        }
                      },
                  
                      detectTouchscreenDevice() {
                        if (window.PointerEvent && ('maxTouchPoints' in navigator)) {
                          if (navigator.maxTouchPoints > 0) {
                            this.isTouchscreenDevice = true;
                          }
                        } else {
                          if (window.matchMedia && window.matchMedia("(any-pointer:coarse)").matches) {
                            this.isTouchscreenDevice = true;
                          } else if (window.TouchEvent || ('ontouchstart' in window)) {
                            this.isTouchscreenDevice = true;
                          }
                        }
                        return this.isTouchscreenDevice;
                      }
                    },
                    components: {
                      NavLink
                    }
                  };
                  </script>
                  
                  <style scoped lang="scss">
                  .primary-navigation-list-dropdown {
                    &__toggle {
                      color: $white;
                  
                      &:hover {
                        color: $blue;
                      }
                    }
                  
                    &__menu {
                      margin-top: 0;
                    }
                  
                    &__dropdown {
                  
                    }
                  }
                  
                  .dropdown-menu-list {
                    &__item {
                  
                    }
                  
                    &__link {
                      &.active,
                      &.nuxt-link-exact-active {
                        border-bottom: 1px solid $blue;
                      }
                    }
                  }
                  </style>
                  

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 2011-08-04
                    • 2018-09-03
                    • 2015-04-22
                    • 2011-05-26
                    • 2017-10-14
                    • 1970-01-01
                    • 2018-10-09
                    • 1970-01-01
                    相关资源
                    最近更新 更多