Search code examples
vue.jsvuejs3vuetify.jsvuetifyjs3

Vue: Why does Vuetify's <v-dialog> @update:model-value event only fire when the v-model's value is false?


Please consider the following Vue 3 code which uses Vuetify 3.4.2:

<template>
  <v-app>
    <v-container>
      <v-text-field v-model="msg" />
    </v-container>
    <v-btn @click="showDialog=true">Click</v-btn>
    <v-dialog v-model="showDialog" @update:model-value="handle"
      >Dialog</v-dialog
    >
  </v-app>
</template>

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

  const msg = ref('Hello World!')
  const showDialog = ref(false)
  const handle = newValue => {
    msg.value = newValue
  }
</script>

There's a Vuetify Play playground to try it out.

When I click the <v-btn> button the <v-dialog> dialog is shown - indicating that the value of showDialog has changed to true. However, the text in the <v-text-field> does not change to true. It's as if the handle() function is not called.

When I click outside the dialog it becomes hidden, the handle() function is called and the text in <v-text-field> changes to false - as expected.

Why is handle() not called when the <v-dialog> model changes to true? How can I change the code to trigger the function when the <v-dialog> becomes visible?


Solution

  • update:model-value is the event that VDialog emits when the change is made from within VDialog. When you set showDialog to true in the parent, that value is passed down to the modelValue prop. The prop value in VDialog updating does not itself trigger an emit. It's also not needed. If the parent changes the v-model value, the parent doesn't need an emit from the child to know it did that.

    What you want in this situation is a watcher

    import { watch } from 'vue'
    ...
    watch(showDialog, newValue => {
      msg.value = newValue.toString()
    })
    

    updated Vue Playground