[Vuejs]-How can I bind value between parent and child component in vue?

0👍

Vue3 SFC Playground

Use v-model correctly – update it with a dedicated event. You can’t change component props directly – they are read-only. In your case I suggest to name your v-model visibility to make it more explicitly. Refer to the Vue’s documentation:

https://vuejs.org/guide/components/v-model.html

If you use a HTML native dialog you should watch your prop and call methods on the dialog’s ref.
I strongly recommend to use the native HTML dialog due much better keyboard navigation and accessibility.

App.vue:

<script setup>

import MyDialog from './MyDialog.vue';
import {ref} from 'vue';
const visible = ref(false);

</script>
<template>
  <button @click="visible=true">Show dialog</button>
  <my-dialog v-model:visible="visible">
    <template #title>My Dialog</template>
    Testing v-model for the dialog's visibility
  </my-dialog>
</template>

MyDialog.vue

<script setup>

const props = defineProps({visible:Boolean});

import {ref, watch, onMounted} from 'vue';
const $dialog = ref();

onMounted(() => {
    watch(() => props.visible, val => val ? $dialog.value.showModal() : $dialog.value.close(), {immediate:true});
});

</script>
<template>
<dialog @close="$emit('update:visible', false)" ref="$dialog">
    <h2><slot name="title"></slot></h2>
    <p><slot></slot></p>
    <button @click="$dialog.close()">Close</button>
</dialog>
</template>

0👍

Dialog

<template>
    <dialog  v-model="visible"></dialog>
</templage>
<script setup>
import { computed } from 'vue'
const prop = defineProps(['visible'])
const emits = defineEmits(['update:visible'])
const visible = computed({
  get() {
    return prop.visible
  },
  set(value) {
    emits('update:visible', value)
  }
})
</script>

0👍

You need to intecept the update to visible from the dialog component and instead re-emit it for the parent component to handle, props should not be directly mutated.

Component A:

<template>
  <dialog v-model:visible="visibleProp" />
</template>
<script setup>
const visibleProp = ref(true);
</script>

Dialog:

<template>
  <dialog  :modelValue="visible" @update:modelValue="$emit('update:visible')"></dialog>
</templage>
<script setup>
const prop = defineProps(['visible'])
<script>

See https://vuejs.org/guide/components/v-model.html for more detail on custom v-models

Leave a comment