Search code examples
vue.jsevent-handlingvuetify.js

Vuetify textarea - How does the event propagation actually work?


I have encountered a strange case with the following usage of components:

<template>
  <v-app>
    <v-container>
      <v-menu v-model="menu" :close-on-content-click="false">
        <template #activator="{ props }">
          <v-btn v-bind="props"> Open </v-btn>
        </template>
        <v-card>
          <v-card-text>
            <v-form>
              <v-textarea label="sample text"></v-textarea>
            </v-form>
          </v-card-text>
          <v-card-actions>
            <v-btn @click="menu = false"> Close</v-btn>
          </v-card-actions>
        </v-card>
      </v-menu>
    </v-container>
  </v-app>
</template>

<script setup>
  import { ref } from 'vue'

  const menu = ref(false)
</script>

Vue Playground link

Usually, when pressing enter inside a v-textarea the result will be a newline added. However, in this situation opening the menu writing something and pressing enter does nothing.

IF I remove the v-card-actions component, pressing enter will add a newline but also close the menu. Which is not the desired behavior (This is a reduce example.).

IF I then add a @keydown.enter.stop="" event handler to the v-textarea, everything works as i wish.

Due to the last step making it work, I suspect that there is something going on concerning the event propagation which is either strange/buggy or which I'm not understanding correctly.

What is going on here?


Solution

  • It looks to be caused by a function on v-menu that runs when the enter keydown event is received. This function calls e.preventDefault(), so prevents the new line from occurring.

    As long as the keydown event stops propagating before the v-menu then this won't happen. You can move the @keydown.enter.stop onto any element between v-textarea and v-card (inclusive) and the new line will be created.