雑魚い技術ブログ

基本、サンプルコードは動確してましぇん

Vue3のテレポートを使ってモーダルを作った時に、ん?となったとこ

職場でNuxt3を使っていて、モーダル画面を作ることになりました。

で、普通にモーダルを作る時と同じ感覚で作ってたら、ファイルの切り出し方で混乱したので整理しときます。

まず、テレポートとは?

頑張って公式の文章から理解しようとしましたが無理でした。。。

サンプルコード見たり、色々調べる中で以下の説明が一番簡潔でわかりやすく感じました。

定義したコンポーネントが属するDOMツリーとは別の場所に、まるでテレポートしたかのようにコンポーネントを移動できる機能です。

出典:Vue.js 3.0 の新機能を試す。 〜 Teleport 編〜 - Qiita

その後このビデオを見ながら一緒にサンプルを作ると、とりあえず機能の理解はしっかりできるかと。

www.vuemastery.com

モーダルを作ろう

まず、普通に1つのファイルでモーダル表示ができるページを作ろうとするとこんな感じになるかと思います。

<!-- app/pages/main.vue -->
<template>
  <div>
    <button @click="showFlg = !showFlg">モーダル開閉</button>
    <!-- メインページのコンテンツ 省略 -->
    :
    <!-- モーダル -->
    <div :v-show="showFlg">
      <!-- 中身省略 -->
      :
    </div>
  </div>
</template>

<script>
export default{
  data(){
    return {
      showFlg: false,
    }
  }
}
</script>

じゃあこのモーダル部分を別ファイルに切り出そうとしたとき、どう分けるでしょうか??

Nuxt2・Vue2までのモーダル

  1. メインページ:モーダル開閉のフックになる要素を配置
  2. モーダルコンポーネント:モーダル画面

他の言語でもこういう感じで分けるかと思います。

<!-- app/pages/main.vue -->
<template>
  <div>
    <button @click="showFlg = !showFlg">モーダル開く</button>
    <!-- メインページのコンテンツ 省略 -->
    :
    <!-- モーダル -->
    <Modal :v-show="showFlg" />
  </div>
</template>

<script>
export default{
  data(){
    return {
      showFlg: false,
    }
  }
}
</script>
<!-- app/components/Modal.vue -->
<template>
  <div>
    <!-- 中身省略 -->
    :
  </div>
</template>

テレポート使ってモーダルを作ってみる

  1. メインページ:モーダルを表示させるためのテレポート先を用意
  2. モーダルコンポーネント:モーダル開閉のフックになる要素+モーダル画面

ほぉ。テレポートは記載箇所にとらわれず、指定した場所にまるっとごっそり移動できる機能でした。

つまり記載と表示を意図的にずらせるため、モーダル関連を一括りのファイルにしても、 テレポート先の記載位置が合っていれば、正しく表示できるってわけなのでした。

<!-- app/pages/main.vue -->
<template>
  <div>
    <Modal />
    <!-- メインページのコンテンツ 省略 -->
    :
    <!-- テレポート先を用意してあげる -->
    <div id="modal-display"></div>
  </div>
</template>
<!-- app/components/Modal.vue -->
<template>
  <div>
    <button @click="showFlg = !showFlg">モーダル開く</button>
    <teleport to="#modal-display">
      <div :v-show="showFlg">
        <!-- 中身省略 -->
        :
      </div>
    </teleport>
  </div>
</template>

<script>
export default{
  data(){
    return {
      showFlg: false,
    }
  }
}
</script>

所感

DOM要素を機能ごとにまとめられるのが新鮮。

今までvueやnuxtでモーダルを作ろうとするとパッケージを入れるか、頑張って自作するしか無かったが、サクッとできるようになったのは良い。

でも記載と表示がずれるので、慣れるまで引っかかりそう。

今まで表示部分に手を入れる場合、ブラウザの開発者ツールを頼りにしていたが、テレポートを使ってそうだったらコードベースで読んだ方がいいのかなと思う。

モーダル以外でテレポートの使い所が思いつかないので、一旦Vue3、Nuxt3以降、モーダル作るときはテレポートに注意!と覚えておこう。