SoFunction
Updated on 2025-04-05

Detailed explanation of how to use Teleport and component nesting hierarchy in VueJs

text

existDOMIn components with relatively complex structure and deep hierarchy nesting, some logic needs to be processed according to the corresponding module business, which belongs to the current component.

But from the view of the entire page application, itDOMIt should be rendered throughoutvueOther places outside the application cannot affect the structure of the component

A more common application scenario: a full-screen modal box that controls the position of elements, which can also be handled, but it is more troublesome

Ideally, we want to bind the event to the element in a specific component, and the specific to control the event to be controlled.DOMThe element structure maintains a certain correlation at the specific location in the same component

Without having to put someDOMThe structure is separated, however, in the same component, the button that triggers the modal box and the modal box themselves are in the same component

Because they are all associated with the switch state of the component, the modal box and the button are rendered together in the applicationDOMWhere the structure is very deep, it will make it very difficult to control the CSS layout position of the modal box

Given such scenarios and difficulties,VueOfficially provided aTeleportComponents can solve this problem very well, so that developers don't need to worry about itDOMStructural issues

01-Component Set When the Component Hierarchy is very deep

For example: There are now two components, parent component and child component. In the descendant component, add a button and a modal box pops up, making it appear vertically and horizontally centered on the page.

As shown below, the parent component is as shown below

<template>
    <div class="App">
        I'm the parent component
        <Child />
    </div>
</template>
<script setup>
    import Child from "./"
</script>
<style>
.App {
    width: 400px;
    height: 400px;
    background:red;
}
</style>

The following isChildComponent, sample code is as follows,We need to add a button in the grandson (descendant) component, click the button, and a pop-up box will pop up, and it will be displayed horizontally and vertically in the center of the page.

<template>
    <div class="child">
      <p>I'm a child component</p>
        <button @click="isModel=true">Open the modal box</button>
        <div class="mask-dialog" v-if="isModel">
             <div class="box">
                  <h2>I'm the title</h2>
                  <div>I'm pop-up content</div>
                  <div>
                      <button @click="isModel=false">closure</button>
                  </div>
             </div>
        </div>
    </div>
</template>
<script setup>
import { ref } from "vue";
let isModel = ref(false);
</script>
<style>
.child {
    width: 300px;
    height:300px;
    background:green;
}
/**Gray mask layer */
  .mask-dialog {
    width: 100%;
    height:100%;
    position:absolute;
    left:0;
    top:0;
    background:rgba(0,0,0,0.5)
  }
  .box {
    width: 200px;
    height:200px;
    position:absolute;
    left:50%;
    top:50%;
    transform:translate(-50%,-50%);
    background:pink;
    text-align:center;
  }
</style>

There is one in the above subcomponentbuttonThe button triggers the modal box to open the current component, which contains the logic to control the display and hidden of the pop-up box. When the nested components are deep and complex

If the parent element has positioning, then when controlling the position of the child element, usecssoftransformorposition:absolute,Reference object changes will destroy the layout structure and somecssstyle

The problem of control will be very painful to solve.

Then thisTeleportComponents are designed to solve this problem.DOMStructural fragments are independent of going outside the component and are not affected by the current component layout structure.

go throughTeleportAfter modification

<template>
    <div class="child">
      <p>I'm a child component</p>
        <button @click="isModel=true">Open the modal box</button>
        <Teleport to="body">
            <div class="mask-dialog" v-if="isModel">
                 <div class="box">
                      <h2>I'm the title1</h2>
                      <div>I'm pop-up content</div>
                      <div>
                          <button @click="isModel=false">closure</button>
                      </div>
                 </div>
            </div>
        </Teleport>  
    </div>
</template>
<script setup>
import { ref } from "vue";
let isModel = ref(false);
</script>
<style>
.child {
    width: 300px;
    height:300px;
    background:green;
}
/**Gray mask layer */
  .mask-dialog {
    width: 100%;
    height:100%;
    position:absolute;
    left:0;
    top:0;
    background:rgba(0,0,0,0.5)
  }
  .box {
    width: 200px;
    height:200px;
    position:absolute;
    left:50%;
    top:50%;
    transform:translate(-50%,-50%);
    background:pink;
    text-align:center;
  }
</style>

<Teleport>Receive oneto propTo specify the destination of the transmission.toThe value of   can be aCSSselector string, orid, it can also be oneDOMElement object. The purpose of this code is to tellVueTransfer the following template fragment tobody Under the tag

&lt;Teleport to="#some-id">html structure code</Teleport>&lt;Teleport to=".some-class"&gt;htmlStructure code&lt;/Teleport&gt;
&lt;Teleport to="body"&gt;htmlStructure code&lt;/Teleport&gt;
&lt;Teleport to="html"&gt;htmlStructure code&lt;/Teleport&gt;

02-Teleport component

It isVueAn official built-in component that can "transmit" a part of the template inside a component to the component'sDOMThe location of the outer layer of the structure is a kind of component that can bring ourhtmlTechnology of moving structures to specified locations

&lt;teleport to="Move to the specified location, which can be html, body, or id, class"&gt;
   It's insideHtmlStructural template content
&lt;/teleport&gt;

Notice

<Teleport> When mounted, transmittedtoThe goal must already exist inDOMmiddle. Ideally, this should be the wholeVueApplicationDOMAn element outside the tree. If the target element is alsoVueRendered, you need to make sure it is mounted<Teleport>The element was mounted first

thisteleportThe specified template ishtml, placed at the specified position in the page. It is conditional and cannot be transmitted at will.

Before installing a component, the target element must exist, i.e., the target cannot be presented by the component itself, and should ideally be located in the entireVueOutside the component tree.

The following code is not OK

&lt;template&gt;
    &lt;div class="header"&gt;
        &lt;Teleport to=".content"&gt;
            &lt;div&gt;I'm the content of the head&lt;/div&gt;
        &lt;/Teleport&gt;
    &lt;/div&gt;
    &lt;div class="footer"&gt;
        Bottom content
        &lt;div class="content"&gt;&lt;/div&gt;
    &lt;/div&gt;
&lt;/template&gt;
&lt;script setup&gt;
&lt;/script&gt;
&lt;style lang="less"&gt;
h1 {
    color: red;
}
&lt;/style&gt; 

03-What you need to know

teleportIt just changed the renderingDOMStructure, it will not affect the logical relationship between components. That is, if<Teleport>Contains a component, then the component is always used with this<teleport>The components of  maintain a logical parent-son relationship. Incomingpropsand triggered events will also work as usual.

This also means that injection from the parent component will work as expected, and the child component will be inVue DevtoolsNested under the parent component, not where the actual content is moved to

The position has moved and is brought to the structural template, but the data logic is still related

04-How to disable Teleport

In some scenarios, it may need to be disabled as appropriate.<Teleport>. For example, we want to render a component as a floating layer on the desktop, but on the mobile side as an inline component. We can pass <Teleport>Dynamically pass in onedisabled propTo deal with these two different situations

<Teleport :disabled="isMobile">
  ...
</Teleport>

HereisMobileThe status can be based on CSS media queryDifferent results of   are updated dynamically

05-When multiple Teleports share targets

A reusable modal box component may have multiple instances at the same time. For such scenarios, multiple<Teleport> The component can mount its content on the same target element, and the order is simply appended in sequence, and the subsequent mounted will be placed at a later position under the target element.

For example, the following use case

<Teleport to=".content">
  <div>A</div>
</Teleport>
<Teleport to=".content">
  <div>B</div>
</Teleport>

The rendering result is

<div class="content">
  <div>A</div>
  <div>B</div>
</div>

Summarize

thisteleportComponents are still very practical in actual development, and can solve the problem that when the component nesting level is very deep, the templates in later components want to be separated from the current component structure.cssDisturbance at the layout level, then you can use thisteleportComponents

The above is a detailed explanation of how to use Teleport and component nesting hierarchy in VueJs. For more information about VueJs using Teleport components, please pay attention to my other related articles!