Vue.jsで Teleport の機能を使うことがあったので、
復習がてらに記事を記載します。
Teleport とは、Vue 3.0で追加された機能です。
これを使うと、要素が DOM 階層に深くネストされてしまうのを防いで、
(指定した)より浅い階層に設置することができるようになるようです。
公式サイトのサンプルコードを記載。
Teleport 使わない場合。
<script setup>
import { ref } from 'vue'
const open = ref(false)
</script>
<template>
<button @click="open = true">Open Modal</button>
<div v-if="open" class="modal">
<p>Hello from the modal!</p>
<button @click="open = false">Close</button>
</div>
</template>
<style scoped>
.modal {
position: fixed;
z-index: 999;
top: 20%;
left: 50%;
width: 300px;
margin-left: -150px;
}
</style>
Teleport 使う場合。(templateの中身だけ)
<button @click="open = true">Open Modal</button>
<Teleport to="body">
<div v-if="open" class="modal">
<p>Hello from the modal!</p>
<button @click="open = false">Close</button>
</div>
</Teleport>
stackblitz 埋め込み。
Teleport 使わない場合。
Teleport 使う場合。
Teleport ありなし、同じ画面に両方表示する。
公式サイトのサンプルコードを修正して、Teleport ありVerとなしVerを、同じ画面に両方表示するようにした。
コード
<script setup>
import { ref } from 'vue';
const open1 = ref(false);
const open2 = ref(false);
</script>
<template>
<button @click="open1 = true">Teleportなし</button>
<button @click="open2 = true">Teleportあり</button>
<div v-if="open1" class="modal">
<p>Teleportなし</p>
<button @click="open1 = false">Close</button>
</div>
<Teleport to="body">
<div v-if="open2" class="modal modal2">
<p>Teleportあり</p>
<button @click="open2 = false">Close</button>
</div>
</Teleport>
</template>
<style scoped>
.modal {
position: fixed;
z-index: 999;
top: 20%;
left: 50%;
width: 300px;
margin-left: -150px;
text-align: center;
background-color: yellow;
}
.modal2 {
background-color: red;
}
</style>
stackblitz 埋め込み。
HTML確認してみた。
F12キーを押してHTMLの階層構造が、どうなっているかを見てみたら、
- Teleport を使わない場合は、ネストの深い場所にModalがある。
- Teleport を使う場合は、body直下に、Modal がある。
<Teleport to="body">で、body直下を指定しているため。
Teleportを使うと、指定した場所に、Modalを設置できることを確認できた。

