Teleport in Vue 3 with Example

Teleport in Vue 3 with Example

Creating the web pages using components is a good idea. So that we can re-use the logic and structure of the design. We have to make a component hierarchy or tree to make the UI better. In Vue.js we are using template string or render function to build the HTML DOM in the components. The Vue compiler will compile it and make the div elements for us

However, sometimes logically, we need one component which could be a child to its parent component, But the component HTML div should not be nest to its parent. Meanwhile we need to place it somewhere else in the DOM. Little bit confusing right.

Generally the HTML tree structure will be the same as component tree structure. But if you want to change one component div’s parent somewhere else in the DOM, we can go for teleport in Vue.js. It is an advanced feature introduced in Vue.js 3. If you are not familiar with Vue.js You can refer to our page Vue Let’s go to the topic in detail.

Teleport in Vue 3 with Example

Teleport

Teleport will change the parent element of a component. Note that teleport will move actual DOM nodes instead of recreating it. This will maintain the same component instance. Teleport has two attributes.

  1. to – String
  2. disabled – Boolean

to – string is a prop denoting a target parent element where the teleport will move it’s content. It is a mandatory prop. This prop can be a valid query selector, or an HTML element (Example : body).

<teleport to="#to-parent-id" /> 
<teleport to=".to-parent-id" /> 
<teleport to="[to-parent-data-teleport]" />

disabled – boolean is a prop which disables the teleport operation. This is an optional Boolean prop. If we apply the disable prop, this will not move the teleport content to the target element. At the same time it will render the elements where you specified the teleport tag just like normal components. A great example for this use case is, streaming the video in either pop up or normally like below,

<teleport to="#popup" :disabled="popupOrInline">
  <video src="./my-movie.mp4">
</teleport>

Teleport in Vue 3 with Example

Generally, we can achieve the same operation without teleport also. If we need to change the positions of the elements but quickly ,the process becomes difficult. But teleport makes the work simple for us. In our example, we are going to teleport a component to HTML  #toPlace div. Firstly we are creating Teleport component as follows

// TeleportComp.vue
<template>
  <div>
    <teleport :to="teleportTo" :disabled="disableTeleport">
      <TeleportChild:imagePath="imagePath" />
    </teleport>
  </div>
</template>

<script>
import TeleportChild from "./TeleportChild.vue";
export default {
  components: {
    TeleportChild,
  },
  props: {
    teleportTo: {
      type: String,
      default: "body",
    },
    imagePath: String,
    disableTeleport: Boolean,
  },
};
</script>

Secondly we are creating the TeleportChild.vue component as follows,

// TeleportChild.vue
<template>
  <img
    :src="imagePath"
    alt="Teleport child Text"
    :style="{ width: '100%', height: '100%' }"
  />
</template>

<script>
export default {
  props: {
    imagePath: String,
    altText: String,
  },
};
</script>

In the above example,  we are using the child component TeleportChild.vue inside the Teleport Component. Note that here, logically TeleportChild.vue component will remain as child for TeleportComp.vue component even when it’s position changed (But actually not). Moreover the Vue.js Dev-tools also will have the same component hierarchy structure. Now we are creating the TeleportDemo.vue file to check the behaviors. Here we are enabling teleport operation based on disableTeleport flag.

// TeleportDemo.vue
<template>
  <div id="toPlace"></div>
  <div :style="{ width: '200px', height: '200px' }">
    <button class="btn" @click="onClickBtn">
      {{ disableTeleport ? "Move to toPlace" : "Come Back" }}
    </button>
    <TeleportComp
      teleportTo="#toPlace"
      imagePath="logo_transparent.png"
      :disableTeleport="disableTeleport"
    />
  </div>
</template>

<script>
import { ref } from "vue";
import TeleportComp from "../components/teleport/TeleportComp.vue";
export default {
  components: {
    TeleportComp,
  },
  setup() {
    let disableTeleport = ref(true);
    const onClickBtn = () => {
      disableTeleport.value = !disableTeleport.value;
    };
    return {
      onClickBtn,
      disableTeleport,
    };
  },
};
</script>
<style scoped>
#toPlace {
  width: 200px;
  height: 200px;
  margin: auto;
  display: flex;
  justify-content: center;
}
.btn {
  background-color: #4999f5;
  border: none;
  color: white;
  padding: 10px;
  font-size: 16px;
  cursor: pointer;
}
.btn:hover {
  background-color: #0417c0;
  color: white;
}
</style>

In the above example, if disableTeleport is set to true, then the teleport component acts as a normal component. if disableTeleport is set to false, the teleport component will be moved to #toPlace div element. Teleport will not change the hierarchy of component tree structure logically. But the effect will reflect in the HTML DOM. Now the image element moved to #toPlace element. You can check the full working example below,

Multiple Teleport in Vue 3 with Example

Now we are going to see multiple teleport operations. Here the same target element will have multiple teleport components. When we move the teleport components, It will follow the moving order and append to the target element.

<teleport to="#toPlace">
  <div>A</div>
</teleport>
<teleport to="#toPlace">
  <div>B</div>
</teleport>

<!-- result-->
<div id="toPlace">
  <div>A</div>
  <div>B</div>
</div>

In the above example, the #toPlace element will have A,B div elements on teleport operation. Now we are creating TeleportMultipleDemo.vue file where we are moving two teleport components to same #toPlace target element. You can refer the full working example below

Summary

  • Teleport will change the parent of a component. Note that teleport will move actual DOM nodes instead of recreating it.
  • Even though teleport changes the parent elements, it will maintain the instances of components.
  • If disabled flag is given, it will render the elements where you specified the teleport tag just like normal components.
  • The same target element will have multiple teleport components.

Reference

Leave a Reply

%d bloggers like this: