'Binding button with keypress in Vue3.0

I am trying to trigger the button when mouse clicked it or a key is pressed and I get confused about communication between components. How should I call pressDown() in KeyButton component from its father component, or is there a better way to implement this function?

Here's my attempt

Container of button

<template>
  <key-button :message="'Msg'" :callback="pressKey" ></key-button>
</template>
<script setup>
import KeyButton from "./KeyButton.vue";
import {ref,onMounted} from "vue";
onMounted(()=>{
  addEventListener('keypress',(e)=>{
    //trigger button
  });
})
const pressKey = () => {
  //exec when button clicked
}
</script>

KeyButton Component

<template>
  <button class="button" :class="{'animate': active}" v-on="{mousedown:pressDown,animationend:triggerAnim}">{{props.message}}</button>
</template>

<script setup>
import {ref,defineProps} from 'vue';
const props = defineProps({
  message: String,
  callback: Function
})
const active = ref(false);
//Function to trigger button
const pressDown = ()=>{
  props.callback();
  triggerAnim();
}
const triggerAnim = ()=>{
  active.value = !active.value;
}

</script>

<style scoped>
button{
  display: flex;
  height: 5rem;
  width: 5rem;
  justify-content: center;
  align-items: center;
  font-size: 2rem;
  color: white;
  border-color: deepskyblue;
  border-width: 0.15rem;
  border-radius: 50%;
  background-color: lightskyblue;
  margin-bottom: 1rem;
  margin-left: 2rem;
  outline: none !important;
}

.animate{
  animation: zoom 0.2s;
}

@keyframes zoom {
  0%{
    transform: scale(1);
  }
  10%{
    transform: scale(0.9);
  }
  100%{
    transform: scale(1);
  }
}
</style>


Solution 1:[1]

You should not pass callbacks as props between components. Vue has a pattern to share functions between components: enter link description here, provide/inject pattern.

Although, I suggest you follow the approach Aside gave to you, and work with event handling provided by vue by emitting an event on child component to the parent.

Solution 2:[2]

You shouldn't pass methods as props in vue as this creates interdependencies among the components and makes them less reusable.

Instead of passing the method you should emit an event from the KeyButton Component on keypress and listen to it in the parent component, like so:

// KeyButton Component
<button @click="$emit('button-pressed')" />

// Parent
<KeyButton @button-pressed="pressKey" />

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Luís Daniel Simões
Solution 2