Vue 3 - Teleports
Vue’s component architecture enables us to build our user interface into components that beautifully organize our business logic and presentation layer. Teleporting is a new feature brought by the release of Vue 3, and it is inspired by React Portals. Same portals, which are a common feature in React, were available in Vue2 under the portal-vue library, now the Vue team added with the help of a third-party plugin named Portal-Vue.
What is Teleport?
Vue 3 comes with a lot of interesting new features and changes that are aimed at making development with the framework a lot easier and maintainable. In this article, we’re going to take a look at Vue 3's new feature called Teleport. Through the early stages of Vue 3, this feature was called Portals but the Vue team eventually decided to call it Teleport. Teleporting, as its name implies, is a component that can make an element go from one component to another. In Vue JS terms, it allows you to define a component in one place, and render it in a different position in the DOM tree, even outside the scope of the Vue app.
How to use it?
The <teleport> tag takes a "to" attribute that specifies where in the DOM you want to teleport an element to. This destination must be somewhere outside the component tree to avoid any kind of interference with other application’s UI components. For this reason, the Vue team recommends putting it below the body tag in the index.html file of your public directory. Vue’s component architecture enables us to build our user interface into components that beautifully organize our business logic and presentation layer. When you’re working with components like modals or notifications, you will notice that their position in the DOM is important.
To use the teleport component in your app, you need to first, add a sibling to the #app element in the html.
<html> <body> <div id="app"></div> <!-- built files will be auto injected --> <div class="loader"></div> <!-- loader component will be injected here --> </body> </html>
Once you've done that, go to your .vue file and use the teleport component:
<template> <teleport to=".loader" v-if="showLoader"> <Loader /> </teleport> <!-- The logic of your component goes below --> </template>
This is it! Now, when the showLoader condition is met, the loader will show in the specified html element.
to— This is a prop that specifies a target element where every content within <teleport> will be rendered. The value of the to prop has to be a valid query selector that identifies an existing CSS class,id or an HTMLElement:
<!-- ok --> <teleport to="#some-id" /> <teleport to=".some-class" /> <teleport to="[data-teleport]" /> <!-- Wrong --> <teleport to="h1" /> <teleport to="some-string" />
disabled— As the name suggests, this prop is a boolean used to disable the teleports functionality. When set to true, the content of <teleport> will be rendered at the location where it was specified. So, it will not be “teleported” to any external target or location. Using our earlier example, if we wanted to disable the teleport for our modal we would add the disabled prop to it like so:
<!-- src/components/HelloWorld.vue --> <teleport to="#my-modal" :disabled="true"> <button @click="showModal = true" >Open Modal</button> <div v-if="showModal" id="myModal"> <div class="modal-content"> <span @click="showModal = false">×</span> <h3>This is the title</h3> <p>This is the content</p> </div> </div> </teleport>
It’s worth adding that you can teleport contents directly to the body and not just to a specified CSS selector. Here’s an example:
<!-- src/components/HelloWorld.vue --> <teleport to="#body"> <button @click="showModal = true">Open Modal</button> <div v-if="showModal" id="myModal"> <div class="modal-content"> <span @click="showModal = false">×</span> <h3>This is the title</h3> <p>This is the content</p> </div> </div> </teleport>
Purpose of the Teleport
The first thing to consider is when and why this Teleport function can come in handy.
Another interesting use case that I am looking forward to trying out is modular apps. A platform like WordPress, allows modules to render into different hooks in the UI and a similar concept can be envisioned with teleport.
When working with larger Vue projects, it is important to organize your codebase in a logical manner. Dealing with certain types of components like modals, notifications, or tooltips, the logic for the template HTML may be in a different file than where we would want to render the element. To be honest these elements are much easier to manage when they are handled entirely separately from the DOM of our Vue app. This is because handling of the nested components can get tricky due to handling the scope of all of its parents.
Teleport is a well-known concept from React known as portals. It was also adopted in Vue 2 through third-party plugins like portal-vue, in Vue 3 it was renamed to teleports and implemented directly by Vue Team. As you can see, using teleport provides you a way to keep your code in the same component, while moving pieces of it into other parts of your page. It simplifies working with elements like modals and popups and makes it extremely easy to render it on top of their DOM. We hope you appreciate the value of the new feature and role in the Vue framework.
If u want to talk about you project - contact us.