Vue Teleport
Render components anywhere in the DOM
🚀 What is Vue Teleport?
Teleport allows you to render a component's template in a different part of the DOM tree, outside your app's hierarchy. Perfect for modals, tooltips, and notifications that need to escape parent styling constraints.
<!-- Component with Teleport -->
<template>
<button @click="showModal = true">Open Modal</button>
<Teleport to="body">
<div v-if="showModal" class="modal">
<p>This renders at the body level!</p>
<button @click="showModal = false">Close</button>
</div>
</Teleport>
</template>
<script setup>
import { ref } from 'vue'
const showModal = ref(false)
</script>
Key Teleport Concepts
Target Selector
Specify where to render content
<Teleport to="body">
<div>Content</div>
</Teleport>
Multiple Teleports
Multiple components to same target
<Teleport to="#modals">
<Modal1 />
</Teleport>
<Teleport to="#modals">
<Modal2 />
</Teleport>
Conditional Teleport
Enable/disable teleport dynamically
<Teleport :disabled="isMobile">
<div>Content</div>
</Teleport>
CSS Selectors
Use any valid CSS selector
<Teleport to="#app">
<Teleport to=".container">
<Teleport to="body">
🔹 Basic Modal Example
Create a modal that renders outside the component hierarchy:
<template>
<div class="app">
<h1>My App</h1>
<button @click="open = true">Show Modal</button>
<Teleport to="body">
<div v-if="open" class="modal-overlay">
<div class="modal-content">
<h2>Modal Title</h2>
<p>This modal is rendered at the body level!</p>
<button @click="open = false">Close</button>
</div>
</div>
</Teleport>
</div>
</template>
<script setup>
import { ref } from 'vue'
const open = ref(false)
</script>
<style scoped>
.modal-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
}
</style>
🔹 Notification System
Teleport notifications to a dedicated container:
<template>
<button @click="notify">Show Notification</button>
<Teleport to="#notifications">
<div v-if="message" class="notification">
{{ message }}
</div>
</Teleport>
</template>
<script setup>
import { ref } from 'vue'
const message = ref('')
function notify() {
message.value = 'Action completed!'
setTimeout(() => message.value = '', 3000)
}
</script>
🔹 Disabled Teleport
Conditionally enable or disable teleport:
<template>
<Teleport to="body" :disabled="!usePortal">
<div class="content">
<p>This content teleports only when usePortal is true</p>
</div>
</Teleport>
<button @click="usePortal = !usePortal">
Toggle Teleport: {{ usePortal }}
</button>
</template>
<script setup>
import { ref } from 'vue'
const usePortal = ref(true)
</script>