JAVASCRIPT

Implementing a Modal Component with Vue 3 Teleport

Learn to create a robust modal or overlay component in Vue 3 using the `Teleport` feature, ensuring proper DOM structure independent of component hierarchy.

// components/MyModal.vue
<template>
  <teleport to="body">
    <div v-if="isVisible" class="modal-backdrop" @click.self="closeModal">
      <div class="modal-content">
        <header class="modal-header">
          <h3>{{ title }}</h3>
          <button class="close-button" @click="closeModal">&times;</button>
        </header>
        <div class="modal-body">
          <slot></slot>
        </div>
        <footer class="modal-footer">
          <button @click="closeModal">Close</button>
        </footer>
      </div>
    </div>
  </teleport>
</template>

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

const props = defineProps({
  isVisible: {
    type: Boolean,
    default: false,
  },
  title: {
    type: String,
    default: 'Modal Title',
  },
});

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

const closeModal = () => {
  emit('close');
};
</script>

<style scoped>
.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: 9999;
}

.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;
}

.modal-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 15px;
}

.close-button {
  background: none;
  border: none;
  font-size: 1.5rem;
  cursor: pointer;
}
</style>

<!-- App.vue (example usage) -->
<template>
  <div>
    <h1>My App</h1>
    <button @click="showModal = true">Open Modal</button>

    <MyModal :isVisible="showModal" title="Important Notice" @close="showModal = false">
      <p>This is the content of the modal. It can be anything you want!</p>
      <p>It's rendered directly into the body thanks to Teleport.</p>
    </MyModal>
  </div>
</template>

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

const showModal = ref(false);
</script>
How it works: This code snippet demonstrates using Vue 3's `Teleport` feature to render a modal component directly into the `body` of the HTML document, regardless of where `MyModal` is used in the component tree. This is crucial for ensuring correct styling, z-index, and accessibility for overlays, preventing issues caused by parent component styling or overflow properties.

Need help integrating this into your project?

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

Hire DigitalCodeLabs