JAVASCRIPT
Displaying Modals/Notifications with Vue 3's Teleport
Leverage Vue 3's Teleport feature to render a component's content into a different DOM location, perfect for modals, tooltips, or global notifications that need to break out of parent styling.
// ModalComponent.vue
<template>
<teleport to="body">
<div v-if="isOpen" class="modal-backdrop" @click.self="closeModal">
<div class="modal-content">
<h3>{{ title }}</h3>
<p><slot>Default modal content.</slot></p>
<button @click="closeModal">Close</button>
</div>
</div>
</teleport>
</template>
<script setup>
import { defineProps, defineEmits } from 'vue';
defineProps({
isOpen: { type: Boolean, required: true },
title: { type: String, default: 'Modal Title' }
});
const emit = defineEmits(['update:isOpen']);
const closeModal = () => {
emit('update:isOpen', false);
};
</script>
<style scoped>
.modal-backdrop {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
justify-content: center;
align-items: center;
z-index: 1000;
}
.modal-content {
background-color: white;
padding: 30px;
border-radius: 8px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
max-width: 500px;
width: 90%;
}
</style>
// App.vue (Usage)
<template>
<div>
<h1>My App</h1>
<button @click="showModal = true">Open Modal</button>
<ModalComponent :is-open="showModal" @update:isOpen="showModal = $event" title="Important Message">
<p>This is dynamic content passed to the modal slot!</p>
</ModalComponent>
<p>Main app content...</p>
</div>
</template>
<script setup>
import { ref } from 'vue';
import ModalComponent from './ModalComponent.vue';
const showModal = ref(false);
</script>
How it works: Vue 3's `<Teleport>` component allows you to render a component's content into a different DOM node that exists outside the current component's DOM hierarchy. This is incredibly useful for features like modals, notifications, or tooltips where you need the content to sit directly under `<body>` to avoid z-index or overflow issues from parent elements. In this snippet, `ModalComponent` uses `<teleport to="body">` to ensure its backdrop and content are rendered directly into the document body, while its state (`isOpen`) and properties are still managed by its parent component, `App.vue`.