Teleport Component in VUe 3

All You Need to Know About Teleport in Vue 3

Vue 3's Teleport allows you to move component templates to different parts of the DOM while preserving their Vue context and reactivity, enabling more flexible and powerful UI rendering across your application.

5 min read

December 2nd, 2024

Nick Mousavi

What is Vue Teleport ?

Teleport is a powerful Vue 3 feature that allows you to move a component's template to a different location in the DOM tree while preserving its vue context and reactivity.

It solves common challenges like rendering modals, tooltips, or overlays that need to break out of the current component's styling or layout constraints.

When a parent component has overflow: hidden or specific layout constraints, rendering a Modal becomes challenging. Teleport solves this by allowing you to move (render) your Modal to a different location in the DOM, ensuring it displays correctly regardless of parent component styling.

How to use Vue Teleport ?

Here is the simplest way possible to use Teleport in Vue 3.

<template>
<Teleport to="body">   <div> My Element </div>
</Teleport>
</template>

Now if you check your body tag in the browser, you can find <div> My Element </div>.

Actually Vue 3 Teleported our element to body tag.

<body>
  <div> My Element </div>
</body>

The to prop in Teleport allows you to specify the target element for rendering, accepting either a CSS selector or a direct DOM node reference.

But the target(to) should be an element that already mounted and exit in the DOM. Otherwise you should use defer

Logical vs Visual Hierarchy

<Teleport> only affects the rendered DOM structure, not the logical component hierarchy. Teleported components retain their parent-child relationships,

So if you used props, events, and dependency injection, they continue to function as expected.🤠

<template>
  <div class="parent-component">
    <Teleport to="body">
      <child-component :message="parentMessage" @some-event="handleChildEvent"/>
    </Teleport>
  </div>
</template>

<script setup>
import ChildComponent from './ChildComponent.vue'

const parentMessage = ref('My prop for child')

const handleChildEvent = (data) => console.log('event from child', data)
</script>

Target Order in Vue Teleport

Based on Vue official doc, several <Teleport> components can target the same DOM element. Content is appended in the order the teleports are mounted.

ComponentA is mounted before componentB and both teleported to body, therefore the structure will be like this:

<body>
  <ComponentA/>
  <ComponentB/>
</body>

Defer

defer is a new prop that you can use from Vue 3.5 an above, it allow us to target to element that appear after our Teleport in the component tree, ensuring the target is available before teleporting.

When defer is set to true, the teleported content waits for the initial render to complete before being mounted to its target location.

How to Disable the Teleport

The disabled prop in Vue's Teleport doesn't remove the Teleport component itself

Instead, it changes how the content is rendered. When disabled is true, the teleported content simply renders in its original component location, maintaining all of its existing component context and behavior.

<template>
<Teleport to="body" :disabled="isDisabled">
  <!-- Teleport Content -->
</Teleport>
</template>

We can conditionally teleport our component to other location or keep it on its location.

Conclusion

<Teleport> is a powerful addition to Vue 3, simplifying the management of UI elements that require specific DOM positioning while maintaining a logical component structure.

10 Questions and Answers Teleport in Vue 3

Teleport is a built-in component that allows you to render a part of a component's template at a different location in the DOM, while maintaining its original Vue component context and reactivity.

<teleport to="body">
  <div>This content will be rendered in the body tag</div>
</teleport>

Yes, Teleported components maintain their full logical hierarchy, meaning they can still receive props, emit events, and use dependency injection just like they would in their original location.

The disabled prop allows you to conditionally render teleported content in its original component location instead of the specified target. When set to true, the content renders where the Teleport component is originally placed.

  • to specifies the target location for rendering (can be a CSS selector or DOM node)
  • disabled determines whether the content should be teleported or rendered in its original location, providing a dynamic rendering strategy

Vue Teleport is a built-in component in Vue 3, providing native support for the portal functionality. In contrast, portal-vue was a third-party plugin used in Vue 2 to achieve similar results. Vue Teleport simplifies the implementation and eliminates the need for external dependencies.

When multiple <Teleport> components target the same DOM element, their content is appended in the order they are mounted. The later mounts appear after earlier ones within the target.

While teleporting outside the Vue app is common, you can teleport within the app. However, the target element must already exist in the DOM when the <Teleport> component mounts. This may require conditional rendering or using the defer prop introduced in Vue 3.5 to delay target resolving.

React Portal and Vue Teleport are both solutions for rendering child components outside of their current DOM hierarchy, which is particularly useful for creating modals, tooltips, and other overlay components. They solve the common issue of component styling and z-index limitations by allowing developers to render content at a different location in the DOM tree while maintaining the original component's React or Vue context.

The key similarity is their core purpose: to break free from the typical component nesting constraints and render components in a different part of the DOM. This is crucial for creating UI elements that need to overlay other content or escape potential styling or positioning restrictions.

// React Portal Example
import React from 'react';
import ReactDOM from 'react-dom';

function ReactModalExample() {
  return ReactDOM.createPortal(
    <div className="modal">
      <h2>React Portal Modal</h2>
      <p>This modal is rendered outside the current DOM hierarchy</p>
    </div>,
    document.body // Renders directly to the body
  );
}
  • API Design:
    • React Portal uses ReactDOM.createPortal() method, which requires explicitly specifying the target DOM element.
    • Vue Teleport uses a built-in <Teleport> component with a declarative to prop, offering a more template-friendly approach.
  • Implementation:
    • React Portal is a method that needs to be imported from 'react-dom'.
    • Vue Teleport is a native component in Vue 3, requiring no additional imports beyond the core Vue library.
  • Context Preservation:
    • Both maintain the original component's context (props, events, state) even when rendering outside the original DOM hierarchy.
    • React Portal preserves the React context through the render method.
    • Vue Teleport maintains the Vue component's context through its component-based approach.
Tags:NuxtVue
Nick Mousavi
A small step forward is still progress.

To get in touch with Nick Mousavi,
please enter your email address below.

© 2020-present Nick Mousavi. All Rights Reserved.

Privacy Policy