JAVASCRIPT

Creating a Reusable Modal Component with Teleport

Build a flexible and accessible modal dialog in Vue 3 using the <Teleport> component to render content outside the current component's DOM tree.

// Modal.vue
<template>
  <teleport to="body">
    <div v-if="isOpen" class="modal-backdrop" @click.self="closeModal">
      <div class="modal-content">
        <button class="close-button" @click="closeModal">X</button>
        <slot></slot>
      </div>
    </div>
  </teleport>
</template>

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

const props = defineProps({
  isOpen: {
    type: Boolean,
    required: true,
  },
});

const emit = defineEmits(['close']);

const closeModal = () => {
  emit('close');
};
</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: white;
  padding: 20px;
  border-radius: 8px;
  min-width: 300px;
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
  position: relative;
}
.close-button {
  position: absolute;
  top: 10px;
  right: 10px;
  border: none;
  background: transparent;
  font-size: 1.2em;
  cursor: pointer;
}
</style>

// App.vue (or any parent component)
<template>
  <div>
    <h1>My App</h1>
    <button @click="showModal = true">Open Modal</button>
    
    <Modal :is-open="showModal" @close="showModal = false">
      <h2>Modal Title</h2>
      <p>This content is rendered inside the modal.</p>
      <p>It's physically outside the root element in the DOM.</p>
    </Modal>
  </div>
</template>

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

const showModal = ref(false);
</script>
How it works: This snippet demonstrates creating a reusable modal component using Vue 3's `<Teleport>` feature. Teleport allows you to render a portion of your component's template into a different part of the DOM, even outside the current Vue app instance. This is particularly useful for modals, notifications, or tooltips, ensuring they are correctly positioned and z-indexed regardless of their parent component's styling. The `Modal.vue` component uses a slot for flexible content and emits a `close` event to be controlled by its parent component.

Need help integrating this into your project?

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

Hire DigitalCodeLabs