JAVASCRIPT

Managing DOM Placement with Vue 3's `Teleport` Component

Leverage Vue 3's built-in `Teleport` component to render components in a different part of the DOM tree, perfect for modals, notifications, and tooltips, avoiding CSS stacking issues.

// public/index.html (ensure a target element exists)
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" href="/favicon.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Vue 3 App</title>
  </head>
  <body>
    <div id="app"></div>
    <div id="teleport-target"></div> <!-- This is our target for teleported content -->
    <script type="module" src="/src/main.js"></script>
  </body>
</html>

// src/components/ModalComponent.vue
<template>
  <teleport to="#teleport-target">
    <div v-if="isOpen" class="modal-backdrop" @click.self="closeModal">
      <div class="modal-content">
        <h2>{{ title }}</h2>
        <p><slot>Default modal content goes here.</slot></p>
        <button @click="closeModal">Close</button>
      </div>
    </div>
  </teleport>
</template>

<script setup>
import { defineProps, defineEmits } from 'vue';

const props = 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: 20px;
  border-radius: 8px;
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
  max-width: 500px;
  width: 90%;
  z-index: 1001;
}
</style>

// src/App.vue
<template>
  <div>
    <h1>My App Content</h1>
    <p>This is the main application content.</p>
    <button @click="openModal">Open Modal</button>

    <ModalComponent :isOpen="isModalOpen" @update:isOpen="isModalOpen = $event" title="Important Notice">
      <p>This content is teleported outside the main app div!</p>
      <p>It helps prevent z-index and overflow issues.</p>
    </ModalComponent>
  </div>
</template>

<script setup>
import { ref } from 'vue';
import ModalComponent from './components/ModalComponent.vue';

const isModalOpen = ref(false);

const openModal = () => {
  isModalOpen.value = true;
};
</script>
How it works: This snippet demonstrates how to use Vue 3's `Teleport` component to render a modal in a separate part of the DOM, specifically outside the main `#app` div. By specifying `to="#teleport-target"`, the `ModalComponent`'s content is moved to the `#teleport-target` element in `public/index.html`. This pattern is highly beneficial for modals, dropdowns, and notifications, as it prevents z-index and overflow issues that can arise when these elements are nested deeply within the component tree.

Need help integrating this into your project?

Our team of expert developers can help you build your custom application from scratch.

Hire DigitalCodeLabs