Vue.js事件:如何检测当鼠标在某个元素上时是否按下了键?

5f0d552i  于 2023-02-19  发布在  Vue.js
关注(0)|答案(2)|浏览(344)

我目前正在Vue.js3中开发一个多项选择组件。
每一项都由一个包含复选框的<div>元素表示。

对于我想要实现的功能,我需要检测鼠标在<div>上按下Shift键的时间。(我的目标是在按下Shift键的同时突出显示上次选中的项目和当前鼠标下的项目之间的所有项目,然后使用Shift +单击将它们全部选中-但这不是重点)。

我尝试使用@mouseover.shift来实现这一点,如下所示:

<div v-for="item in items"
         class="item"
         @mouseover.shift="onMouseOverShift(item)"
    >

不幸的是,虽然@mouseover.shift可以很好地检测鼠标进入<div>时是否按下Shift,但当鼠标已经进入<div>时按下Shift键时不会触发。
你知道什么是最好的方法来实现我正在寻找的吗?

64jmpszr

64jmpszr1#

我想你可以这样使用:

<div v-for="item in items"
    class="item"
    @mouseenter="isMouseOver = true"
    @mouseleave="isMouseOver = false"
    @keypress.shift="onMouseOverShift(item)"
/>

然后在方法onMouseOverShift上检查是否为鼠标悬停

ej83mcc0

ej83mcc02#

我不认为你可以检测到div上的按键,或者至少不可靠,你最好的选择可能是将鼠标事件与全局键监视器结合起来。
在Vue 3合成API中,这看起来像这样:
在组件设置中:

const hoveredItem = ref(null)
const shiftPressed = useShiftKeyWatcher()
const selectedItem = computed(() => shiftPressed.value ? hoveredItem.value : null)

在模板中:

<div v-for="item in items"
         class="item"
         @mouseenter="selectedItem = item"
         @mouseleave="selectedItem = null"
    >...</div>

那么useShiftKeyWatcher的composable将如下所示:

import { ref, onMounted, onUnmounted } from "vue";

export function useShiftKeyWatcher() {
  const shiftPressed = ref(false);

  function checkKeyDown(event) {
    shiftPressed.value = event.key === "Shift";
  }

  function checkKeyUp(event) {
    shiftPressed.value &&= event.key !== "Shift";
  }

  onMounted(() => window.addEventListener("keydown", checkKeyDown));
  onMounted(() => window.addEventListener("keyup", checkKeyUp));
  onUnmounted(() => window.removeEventListener("keydown", checkKeyDown));
  onUnmounted(() => window.removeEventListener("keyup", checkKeyUp));

  return shiftPressed;
}

下面是一个sandbox(您需要单击预览区域一次,以使关键事件转到内部文档)

相关问题