Vue 3: Simulate button click and pass the same $event as when actually clicked

Viewed 323

I have the following button to which I'm adding a tailwind animate-pulse when it's clicked, which then is removed after the animation has finished playing:

<button              
    class="
        bg-transparent
        text-black
        font-bold
        py-2
        px-4
        rounded-sm
        uppercase                
    "
    v-bind:class="{
        'hover:bg-magnolia-700': hasResponded,
        'opacity-30': !hasResponded,
    }"                   
    v-on:click="($event) => $event.target.classList.add('animate-pulse')"
    v-on:animationend="($event) => $event.target.classList.remove('animate-pulse')"
    ref="nextButton"
>
    Next
</button>

I also have an eventListener that checks if the right or left arrows are pressed on the keyboard:

  created() {
    var self = this;
    window.addEventListener("keydown", function (e) {
      switch (e.key) {
        case "ArrowLeft":
          self.clickPrevious();
          break;
        case "ArrowRight":
          this.$refs.nextButton.click();
      }
    });
  },

As you can see, I want to simulate the button click by this.$refs.nextButton.click();. However, this results in the error:

SingleItemSection.vue:281 Uncaught (in promise) TypeError: Cannot read properties of null (reading 'classList')

Since the actual button isn't passed ($event.target) when using the keydown-Listener. How can I simulate this, as if the user was to click the actual button (i.e., passing the same $event)?

1 Answers

I would just add these two methods without parameter and call them from the template and the event listener the same way:

created() {
    const self = this;
    window.addEventListener("keydown", function (e) {
      switch (e.key) {
        case "ArrowLeft":
          self.addAnimateToPrev();
          break;
        case "ArrowRight":
          self.addAnimateToNext();
      }
    });
  },
methods: {
    addAnimateToNext() {
        this.$refs.nextButton.classList.add('animate-pulse')
    },
    addAnimateToPrev() {
        this.$refs.prevButton.classList.add('animate-pulse')
    }
}

and in the template: v-on:click="addAnimateToNext"

Related