Reputation: 4008
I want to build a simple open/close Modal, using Vue3 composition API, but it doesn't work.
If I use v-if
(as in the code below) the modal doesn't open, if I use v-show
the modal opens but the close button doesn't work.
As an addition, add a eventListener
for ESC key, and then remove it on unMounted
.
App.vue
<div class="min-h-screen flex items-center justify-center">
<button @click="isModalOpen = true" type="button" class="btn btn-blue">Open Modal</button>
</div>
<announcement-modal
v-if="isModalOpen"
@click="isModalOpen = true"
v-model:isOpen="isModalOpen">
</announcement-modal>
</div>
</template>
<script>
import { ref } from "vue";
import AnnouncementModal from "./components/AnnouncementModal";
export default {
components: {
AnnouncementModal,
},
setup() {
const isModalOpen = ref(false);
return {
isModalOpen,
}
},
}
</script>
Announcement.vue
<div class="text-center">
<button @click="closeModal" type="button" class="btn btn-blue">
Dismiss
</button>
</div>
</div>
</div>
</template>
<script>
import { onUnmounted } from "vue"
export default {
props: ["isOpen"],
setup(props, context) {
onUnmounted(function () {
console.log("after unmounted")
});
function closeModal() {
context.emit("update:is-open", false);
}
return {
closeModal
}
}
}
Upvotes: 0
Views: 6579
Reputation: 8368
The @click="isModalOpen = true"
is immediately opening it every time you click to close the modal.
Remove this event handler and it should work:
const app = Vue.createApp({
setup() {
const isModalOpen = Vue.ref(false);
return {
isModalOpen
}
},
});
app.component('announcement-modal', {
template: `<div class="text-center">
<button @click="closeModal" type="button" class="btn btn-blue">
Dismiss
</button>
</div>`,
setup(props, context) {
Vue.onUnmounted(function() {
console.log("after unmounted")
});
function closeModal() {
context.emit("update:is-open", false);
}
return {
closeModal
}
}
})
app.mount('#app')
<script src="https://unpkg.com/vue@next"></script>
<div id="app">
<div class="min-h-screen flex items-center justify-center">
<button @click="isModalOpen = true" type="button" class="btn btn-blue">Open Modal</button>
</div>
<announcement-modal v-if="isModalOpen" v-model:is-open="isModalOpen"></announcement-modal>
</div>
Also, as @Dan said, the v-model:isOpen="isModalOpen"
shouldn't be camelCase.
Upvotes: 2