In your index.vue you are binding show_form to the modal. However, it is not reactive. You should also use ref() for your show_form variable.
Oct 24, 2022
4
Level 9
Headless UI Dialog not displaying
I can't get this dialog to work at all, this is my code
//MODAL.VUE
<script setup>
import { ref } from 'vue'
import {
TransitionRoot,
TransitionChild,
Dialog,
DialogOverlay,
DialogTitle,
} from '@headlessui/vue'
const props = defineProps({
show: {
type: Boolean,
default: false
}
})
const isOpen = ref(props.show);
const closeModal = function() {
isOpen.value = false
}
</script>
<template>
<TransitionRoot appear :show="isOpen" as="template">
<Dialog as="div" @close="closeModal">
<div class="fixed inset-0 z-10 overflow-y-auto bg-gray-800 bg-opacity-50">
<div class="min-h-screen px-4 text-center">
<TransitionChild
as="template"
enter="duration-300 ease-out"
enter-from="opacity-0"
enter-to="opacity-100"
leave="duration-200 ease-in"
leave-from="opacity-100"
leave-to="opacity-0">
<DialogOverlay class="fixed inset-0" />
</TransitionChild>
<span class="inline-block h-screen align-middle" aria-hidden="true">​</span>
<TransitionChild
as="template"
enter="duration-300 ease-out"
enter-from="opacity-0 scale-95"
enter-to="opacity-100 scale-100"
leave="duration-200 ease-in"
leave-from="opacity-100 scale-100"
leave-to="opacity-0 scale-95">
<div
class="inline-block w-full max-w-md p-6 my-8 overflow-hidden text-left align-middle
transition-all transform bg-white shadow-md rounded">
<slot></slot>
</div>
</TransitionChild>
</div>
</div>
</Dialog>
</TransitionRoot>
</template>
INDEX.VUE
<script setup>
import BreezeAuthenticatedLayout from '@/Layouts/Authenticated.vue';
import {reactive, watch, ref, defineComponent} from "vue";
import Modal from '@/Components/Modal';
let show_form = false;
const openModal = () => {
show_form = true;
}
</script>
<template>
<BreezeAuthenticatedLayout>
<button @click="openModal">Create</button>
<modal :show="show_form">
<template v-slot:default>
<h1>
Modal Dialog
</h1>
</template>
</modal>
</BreezeAuthenticatedLayout>
</template>
What am I doing wrong? I tried with the approach on the example but I couldn't get that to work either so I was trying to a prop but I haven't had any luck.
Level 30
@msslgomez Exactly, props only have a one-way data flow. Having 2 different booleans to control the state is not recommended.
As the property show in your modal.vue is responsible to display your modal, I would recommend removing the isOpen ref.
To close the modal, you should use an emit. This way, you will be able to listen to the close event in index.vue to disable the modal again.
// modal.vue
<script setup>
const emit = defineEmits([
'close',
])
</script>
<template>
<TransitionRoot appear :show="show" as="template">
<Dialog as="div" @close="emit('close')">
<!-- ... -->
</Dialog>
</TransitionRoot>
</template>
// index.vue
<script setup>
const closeModal = () => {
show_form = false;
}
</script>
<template>
<modal :show="show_form" v-on:close="closeModal()">
<!-- ... -->
</modal>
</template>
Please or to participate in this conversation.