JAVASCRIPT
Use Teleport to Render Modals Outside Component Tree
Use Vue 3's `<Teleport>` component to render content like modals into a different part of the DOM. Enhances accessibility and avoids z-index issues.
// App.vue (Parent component)
<script setup>
import { ref } from 'vue';
import MyModal from './components/MyModal.vue';
const showModal = ref(false);
</script>
<template>
<header>
<h1>My Application</h1>
<button @click="showModal = true">Open Modal</button>
</header>
<main>
<p>This is the main content of the application.</p>
<p>The modal will appear outside of this main element, in the body.</p>
</main>
<MyModal :show="showModal" @close="showModal = false" />
</template>
// components/MyModal.vue
<script setup>
import { defineProps, defineEmits } from 'vue';
const props = defineProps({
show: Boolean,
});
const emit = defineEmits(['close']);
const closeModal = () => {
emit('close');
};
</script>
<template>
<Teleport to="#modals-container">
<transition name="modal">
<div v-if="show" class="modal-backdrop" @click.self="closeModal">
<div class="modal-content">
<h3>Modal Title</h3>
<p>This is the content of the modal.</p>
<button @click="closeModal">Close</button>
</div>
</div>
</transition>
</Teleport>
</template>
/*
// public/index.html (Ensure you have this target element)
<!DOCTYPE html>
<html lang="">
<head>...</head>
<body>
<div id="app"></div>
<div id="modals-container"></div> <!-- This is the target for Teleport -->
</body>
</html>
// Minimal CSS for demonstration (e.g., in App.vue style block or global CSS)
.modal-backdrop {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
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: 20px;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.33);
}
.modal-enter-active, .modal-leave-active {
transition: opacity 0.3s ease;
}
.modal-enter-from, .modal-leave-to {
opacity: 0;
}
*/
How it works: The `Teleport` component in Vue 3 allows you to render a part of your component's template into a DOM node that exists outside the hierarchy of that component. This is incredibly useful for things like modals, tooltips, or notifications, where you want to control their rendering location (e.g., directly under `body` or a dedicated `#modals-container` element) to avoid z-index or styling issues caused by parent component's CSS.