ryoのぼやき

技術についての学習内容のまとめです。

【Vue.js】Vue3のTeleport(Portal)の使い方

この記事の内容

Vue3.0で追加される機能の1つであるTeleportを使ってみたので、
どういう時に使うのか、どのように使うのか、感想を書いてみようと思います。

※Vue3の環境構築については、下記に書きました。
【Vue.js】Vue-cliでVue3の開発環境を構築する - ryoのぼやき

Teleportでできること

Teleportを使うことで、
コンポーネント内の一部を、
DOM上の任意の位置に移動させることができます。

どういう時に使うか

基本的に、Vue.jsではコンポーネントをベースとしてUIを構築します。
そうすることで、スタイルやロジックなどをコンポーネントに閉じることができるメリットがあります。
しかし、コンポーネント入れ子構造が深くなった時に、
コンポーネント自身の外側に、UIを持っていきたいシーンが出てきます。
そういった時がTeleportの使い時です。
例えば、モーダルが主な利用シーンとして挙げられます。

どのように使うか

例えば、何かしらの結果を表示するResultというコンポーネントがあるとします。
(※templateのみ抜粋)

<!-- Result.vue -->
<template>
  <Teleport to="#result-location">
    <div class="result-panel" v-show="isShowResult">
      <div>Result is...</div>
      <span>{{ result }}</span>
    </div>
  </Teleport>
  <button @click="showResult">Show Result</button>
</template>


そして、Home.vueで、Resultコンポーネントを持つとします。
(※templateのみ抜粋)

<!-- Home.vue -->
<template>
  <div id="result-location"/>
  <Result/>
</template>


使い方は、
1. タグで、他のDOM上の位置に移動させる部分を囲う。
2. タグに to="セレクタ"で移動させる位置のセレクタを指定する。
だけです。

上の例だと、ボタンを選択すると、
Home.vueの<div id="result-location"/>
<Teleport>で囲った部分が表示されます。

※Sample
f:id:greko_prg:20200506225751p:plain


補足

PortalからTeleportに

このTeleportですが、
もともとは、Portalという名前で実装されていました。
しかし、WICGのPortalsとコンフリクトしていたという理由から、
Teleportという名前に変更されたようです。

Portals


targetからtoに

また、セレクタを指定するプロパティのtoですが、
これも前は、targetという名前で実装されていました。
こちらも、WICGのPortalとのコンフリクトを避けるという理由で、
toに変更されたようです。

まとめ

Vueでは、入れ子構造が深くなることで、
きれいな形で実装ができず困るシーンはよくあると思います。
それが、このTeleportが解決の糸口になってくると思うので、
うまく使っていきたいと思いました。

参考

[Teleport RFC]

rfcs/0025-teleport.md at master · vuejs/rfcs · GitHub

[Rename to ]

refactor: rename `<portal>` to `<teleport>` · vuejs/vue-next@eee5095 · GitHub

[kazuponさんのスライド]

まもなくやってくる Vue.js 3 - Speaker Deck