如何处理 Vue3 中的“keydown.esc”事件?

lui*_*7up 3 vue.js vuejs3

我有一个组件,如果变量为真,它<Parent>就会呈现该组件。<Modal>showModal

该变量在组件的函数showModal中定义。setup(){}<Parent>

我想在用户执行以下操作时关闭模式:

  1. 单击关闭按钮
  2. 当他们按下 ESC 按钮时

父组件

<template>
  <Modal v-if="isShownModal" @clickedModalClose="isShownModal=false" @keydown.esc="isShownModal=false">
  //removed some code for clarity purposes
</template>

<script>
export default {
  components: {Modal},
  setup(){

    const isShownModal = ref(false)
    ...
Run Code Online (Sandbox Code Playgroud)

注意@clickedModalClose="isShownModal=false"@keydown.esc="isShownModal=false"

模态组件

<template>

  <div class="modal is-active">
    <div class="modal-background"></div>  
    
    <div class="modal-content box">
      <slot name="header"></slot>
      <slot name="body"></slot>  
    </div>
  
    <!-- Listen to a custom event @clicked-modal-close (v-on) --> 
    <button @click="$emit('clickedModalClose')" class="modal-close is-large" aria-label="close"></button>
  </div>
  
</template>
Run Code Online (Sandbox Code Playgroud)

要关闭模式,当在子组件中单击关闭按钮时,我将发出一个事件并侦听该事件@clickedModalClose,并按预期正确关闭模式

尽管如此,当我按下 ESC 按钮时,即使我在 Modal 组件上声明了事件处理程序,也没有任何反应:<Modal v-if="isShownModal" @clickedModalClose="isShownModal=false" @keydown.esc="isShownModal=false">

我还尝试将 附加@keydown.esc="closeTheModal()"到 中的 DIV 和template标记,并在函数中以编程方式<Modal>发出事件,但无济于事clickedModalClosecloseTheModal()

请有人解释一下这个问题:/

更新

正确答案是@blackgreen 给出的

渲染组件后,为了处理 ESC 事件,该事件必须附加到组件内的 DOM 元素。

我所做的只是在模态关闭按钮上使用模板引用,使其在挂钩中可用onMounted(){}并调用focus()其上的方法

父组件

<Modal @keydown.esc="isShownModal=false">
Run Code Online (Sandbox Code Playgroud)

子组件

<template>
<button ref="closingButton" class="modal-close is-large" aria-label="close"></button>
</template>
Run Code Online (Sandbox Code Playgroud)

在 JS 部分:

<script>
import {ref, onMounted} from 'vue';
export default {
  setup(props, context){
    
    const closingButton = ref(null)
    onMounted(()=>{
      closingButton.value.focus()
    })

    return {closingButton}

  }
}
Run Code Online (Sandbox Code Playgroud)

bla*_*een 5

绑定@keydown.esc是正确的(示范小提琴)。

但要真正触发事件,声明侦听器的元素必须处于焦点位置。

这个小提琴示例中,mounted钩子将焦点设置在一个<div>元素上tabindex=0(一个技巧,以便它可以拥有焦点)。如果在该 div 获得焦点时按 Esc,您也会看到计数器在增加。