0👍
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>
- [Vuejs]-Handling errors from an array input field from Laravel with VuejS
- [Vuejs]-How to pass properties of a slot from child to parent
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