如何实现 Vue 自定义组件中 hover 事件以及 v-model

Vue
586
0
0
2022-04-06

在CSS中,很容易在鼠标hover时进行更改,只需:

.item {
  background: blue;
}

.item:hover {
  background: green;
}

在Vue中,它会变得更复杂一些,因为我们没有内置这个功能。我们必须自己实现这些。不过别担心,工作量不是很大。

监听正确的事件

那么,我们需要监听哪些事件?

我们想知道什么时候鼠标悬停在元素上,这可以通过跟踪鼠标何时进入元素以及何时离开元素来确定。为了跟踪鼠标何时离开,可以使用mouseleave事件。

检测鼠标何时进入可以通过相应的mouseenter事件来完成,但是我们不使用这个。

原因是在深度嵌套 DOM 树上使用mouseenter时可能会出现严重的性能问题。这是因为mouseenter向输入的元素以及每个单独的祖先元素触发一个唯一的事件。

那我们会用什么来代替呢?

我们使用mouseover事件。

二者的本质区别在于,mouseenter不会冒泡,简单的说,它不会被它本身的子元素的状态影响到.但是mouseover就会被它的子元素影响到,在触发子元素的时候,mouseover会冒泡触发它的父元素.(想要阻止mouseover的冒泡事件就用mouseenter)

为了把知识点串联起来,我们使用Vue 事件侦听鼠标进入和离开时的状态,并相应地更新状态。

<template>
  <div
    @mouseover="hover = true"
    @mouseleave="hover = false"
  />
</template>
----------------------------------

export default {
  data() {
    return {
      hover: false,
    };
  }
}

现在通过变量 hover 就可以响应鼠标的进入和移出。

在鼠标悬停时显示一个元素

如果希望显示基于悬停状态的元素,可以将其与v-if指令配对

<template>
  <div> 
    <span
      @mouseover="hover = true"
      @mouseleave="hover = false"
    >
      鼠标悬停时显示该内容
    </span> 
    <span v-if="hover">这里是秘密消息</span> 
  </div>
</template>

-------------------------------------------------

export default {
  data() {
    return {
      hover: false,
    };
  }
}

鼠标悬停时切换样式类

还可以做类似的事情来切换类

<template>
  <div> 
    <span
      @mouseover="hover = true"
      @mouseleave="hover = false" 
      :class="{ active: hover }"
    >
      Hover me to change the background!
    </span> 
  </div>
</template>
-------------------------------------------

export default {
  data() {
    return {
      hover: false,
    };
  }
}
-------------------------------------------

.active {
  background: green;
}

虽然这是可行的,但不是最好的解决方案。

对于这种情况,最好使用CSS

<template>
  <span>
    Hover me to change the background!
  </span>
</template>

----------------------------------------

span:hover {
  background: green;
}

将鼠标悬停在一个Vue组件上

如果你想要使用一个Vue组件来实现这种行为,那么我们需要做一些轻微的修改。我们不能像以前那样听mouseovermouseleave事件。

如果Vue组件不发出那些事件,那么我们就不能监听它们。

相反,我们可以添加.native事件修饰符来直接监听定制Vue组件上的DOM事件。

<template>
  <my-custom-component
    @mouseover.native="hover = true"
    @mouseleave.native="hover = false"
  />
</template>
--------------------------------------
export default {
  data() {
    return {
      hover: false,
    };
  }
}

使用.native,我们侦听本地DOM事件,而不是从Vue组件发出的事件。

接着我们来看看如何在自定义组件中 实现 v-model

虽然v-model是向普通组件添加双向数据绑定的强大功能,但是如何向自己的自定义组件添加对v-model的支持并不总是那么容易,但其实很简单。