コンテンツにスキップ
トップに戻る
このページの内容

PortalVue 2からの移行

PortalVue 3は、Vue 3が提供する新しい機能を使用してコードベースを最適化し、その過程でAPIと機能を少し修正し、不要な部分をクリーンアップするために、完全に書き直されました。

利用者の視点からは、それほど多くの変更はありません。そのため、ほとんどのユースケースはそのまま動作し続けるか、動作させるために少し調整するだけで済みます。

注目すべき例外の1つは<MountingPortal>です。これはこのリリースで削除され、通常のPortalPortalTargetをマウントするための小さなユーティリティ関数に置き換えられました(以下の*変更*を参照)。

補足:Vue 3とTeleport

Vue 3に既に慣れている開発者が抱く可能性のある疑問の1つは

「このライブラリは本当にまだ必要なのでしょうか? Vue 3には<Teleport>が搭載されています!」

正直な答えは、モーダルを<body>などに移動するような典型的なユースケースでは、このライブラリはもう必要ないでしょう。しかし、アプリ*内*で、あるコンポーネントから別のコンポーネントにコンテンツを移動する場合、<Teleport>だけでは適切な選択肢ではなく、このライブラリを使用することでおそらくまだメリットが得られます。

ここで注意すべき点の1つは、PortalVueは内部で*まだ*<Teleport>を使用していないことです。その決定の主な理由は、PortalVue 3をTeleportの上に再構築した場合、移行を困難にする可能性のある動作の違いがさらに多くなるためです。

そのため、PortalVue 3は、Vue 2アプリでPortalVue 2を使用していた場合とほぼ同じ動作を提供する一種の移行リリースと考えてください。ただし、以前のバージョンにあった注意点のほとんども含まれています。

私たちは、後で別のメジャーバージョンをリリースする予定です(おそらく新しい独立したライブラリとして)。これはTeleportの上に構築されます。その時点で、Vue 3アプリで新しいバージョンに自分のペースで移行できます。

移行戦略

PortalおよびPortalTargetコンポーネントは、Vue 3では不要になったslim(下記参照)などのプロパティをいくつか失っただけなので、基本的なユースケースの移行は非常に簡単です。

いくつかの修正が必要な注目すべき破壊的な変更は、2つのユースケースに影響します

  1. PortalTarget側で定義されたトランジション
  2. MountingPortalの削除。これは、1つのエッジケース(multipleプロパティ)を除いて、Teleportでより適切に解決されます。このエッジケースについては、以下で移行パスについて説明します。

変更点一覧

インストール

Vueアプリを作成し、プラグインを登録するグローバルAPIが少し変更されたため、プラグインのインストールも少し変更する必要があります。

詳細な手順については、インストールの章を参照してください。

Portalコンポーネント

slimプロパティの削除

Vue 3では、コンポーネントにルート要素が必要なくなったため、slimは不要になりました。 Portalは、スロットコンテンツの要素数に関係なく、ルート要素をレンダリングしなくなりました。

ラッピング要素が必要な場合は、<portal>を自分で要素でラップしてください

html
<!-- Renders no element -->
<portal to="someTarget"></portal>

<!-- Wrap it in an element if you need it encapsulated i.e. for styling -->
<div>
  <portal to="someTarget"></portal>
</div>

PortalTargetコンポーネント

slimプロパティの削除

Vue 3では、コンポーネントにルート要素が必要なくなったため、slimは不要になりました。 Portalは、スロットコンテンツの要素数に関係なく、ルート要素をレンダリングしなくなりました。

ラッピング要素が必要な場合は、<portal>を自分で要素でラップしてください

html
<!-- will not render its content in a root element -->
<portal-target name="someTarget" />

<!-- Wrap it in an element if you need it encapsulated i.e. for styling -->
<div>
  <portal-target name="someTarget" />
</div>

新規:v-slot:wrapper

複数のPortalからのコンテンツを個別にマークアップでラップするために使用できる、追加の名前付きスロットをPortalTargetに渡すことができるようになりました

html
<portal-target>
<portal-target name="target">
  <template v-slot:wrapper="nodes">
    <div class="some fancy box styles">
      <component :is="node" v-for="node in nodes" />
    </div>
  </template>
</portal-target>

参照:PortalTarget API:ラッパースロット

transitiontransition-eventsプロパティの削除。

これらのプロパティの代わりに、新しいv-slot:wrapperを使用して、コンテンツを<transition>または<transition-group>コンポーネントでラップできるようになりました。 詳細については、こちらのドキュメントを参照してください

削除:MountingPortal

このコンポーネントは削除されました。ユースケースに応じて、2つの代替移行パスがあります

  1. 1つのPortalからのみコンテンツを移動する場合:代わりにVue独自のTeleportを使用します(Teleportドキュメント
  2. 複数の場所から同じマウントされたPortalにコンテンツを移動する場合:createPortalTarget()ユーティリティ関数を使用します
html
<template>
  <portal to="target-name">
    <p>This is the content to move</p>
  </portal>
</template>

<script>
import { createPortalTarget } from 'portal-vue'

export default {

  created() {
    createPortalTarget('#id-of-target-element', {
      name: 'target-name'
      // portal props
    })
  }
}
</script>

実際には、この関数は、他のすべてのPortalコンポーネントがこの単一のPortalTargetにコンテンツを移動できるように、よりグローバルな場所で一度呼び出す可能性が高くなります。

ワームホール

ワームホールは、PortalコンポーネントとPortalTargetコンポーネントを接続する「ストア」です。 PortalVue 2では、シングルトンでした。つまり、1つのページ上のすべてのアプリとライブラリがto=""名の同じ名前空間を共有していました。

PortalVue 3は、プラグインをインストールするときにアプリ内のすべてのコンポーネントにデフォルトインスタンスを提供しますが、必要に応じて独自のインスタンスを作成し、デフォルトインスタンスの代わりに使用できるようになりました。

詳細はこちらをご覧ください

テスト