How to use Teleport in Vue to Move Parts of Templates

Johnny Simpson - Jul 31 '22 - - Dev Community

Normally, when we create components in Vue they naturally appear within the DOM structure where we'd expect them to be. However, sometimes this doesn't make sense. A good example of this is a modal - normally, a modal should appear on top of everything on the page - so if we create it within a component where it logically makes sense, it may appear behind certain HTML elements or require some weird CSS styling to get it to the top.

Fortunately, there is an easy way to solve for this problem in Vue, called <Teleport>. The <Teleport> tag lets us define something within a component, and then "teleport" it anywhere we want in the code. Let's look at how it works.

How Teleport works in Vue

Suppose we have a simple component in Vue called Modal.vue which contains a modal. It looks a little like this:

<script>
export default {
    data() {
        return {
            display: false
        }
    }
}
</script>
<template>
    <button id="show-modal" @click="display == true ? display = false : display = true">Show Modal</button>
    <div class="modal" v-if="display">
        My Modal
    </div>
</template>
Enter fullscreen mode Exit fullscreen mode

In our structure, this modal sits quite deep in our application structure:
Teleportation App Structure Vue

Since Modal.vue is so deep in our structure, it may not appear on top of the rest of our content as we want. As such, we'd ideally want it to be a direct child of the body tag. Using <Teleport>, We can adjust our component to "teleport" it to be a direct child of the body tag like so:

<script>
export default {
    data() {
        return {
            display: false
        }
    }
}
</script>
<template>
    <button id="show-modal" @click="display == true ? display = false : display = true">Show Modal</button>
    <Teleport to="body">
        <div class="modal" v-if="display">
            My Modal
        </div>
    </Teleport>
</template>
Enter fullscreen mode Exit fullscreen mode

The to attribute of Teleport is expected to be a valid CSS selector. Now our .modal div will be teleported to be a direct child of the body, so it will always appear on top, rather than being deeply nested within our Vue structure.

Disabling a Teleport tag

We can disable a Teleport tag based on certain logic using the :disabled attribute. For example, we could check for the value of myToggle being set to true, by using the following code:

<Teleport :disabled="myToggle"></Teleport>
Enter fullscreen mode Exit fullscreen mode

Above, if myToggle is set to true, the Teleport simply won't work, meaning we can only enable it when we want to. As such, Teleport is a very useful tag in Vue for adjusting where and when we see certain content. It's also OK to use multiple Teleport tags within the same Vue template.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .