PortalVue 2からの移行
PortalVue 3は、Vue 3が提供する新しい機能を使用してコードベースを最適化し、その過程でAPIと機能を少し修正し、不要な部分をクリーンアップするために、完全に書き直されました。
利用者の視点からは、それほど多くの変更はありません。そのため、ほとんどのユースケースはそのまま動作し続けるか、動作させるために少し調整するだけで済みます。
注目すべき例外の1つは<MountingPortal>
です。これはこのリリースで削除され、通常のPortal
のPortalTarget
をマウントするための小さなユーティリティ関数に置き換えられました(以下の*変更*を参照)。
補足: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つのユースケースに影響します
PortalTarget
側で定義されたトランジションMountingPortal
の削除。これは、1つのエッジケース(multiple
プロパティ)を除いて、Teleport
でより適切に解決されます。このエッジケースについては、以下で移行パスについて説明します。
変更点一覧
インストール
Vueアプリを作成し、プラグインを登録するグローバルAPIが少し変更されたため、プラグインのインストールも少し変更する必要があります。
詳細な手順については、インストールの章を参照してください。
Portalコンポーネント
slim
プロパティの削除
Vue 3では、コンポーネントにルート要素が必要なくなったため、slim
は不要になりました。 Portal
は、スロットコンテンツの要素数に関係なく、ルート要素をレンダリングしなくなりました。
ラッピング要素が必要な場合は、<portal>
を自分で要素でラップしてください
<!-- 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>
を自分で要素でラップしてください
<!-- 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
に渡すことができるようになりました
<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>
transition
、transition-events
プロパティの削除。
これらのプロパティの代わりに、新しいv-slot:wrapper
を使用して、コンテンツを<transition>
または<transition-group>
コンポーネントでラップできるようになりました。 詳細については、こちらのドキュメントを参照してください
削除:MountingPortal
このコンポーネントは削除されました。ユースケースに応じて、2つの代替移行パスがあります
- 1つの
Portal
からのみコンテンツを移動する場合:代わりにVue独自のTeleport
を使用します(Teleportドキュメント) - 複数の場所から同じマウントされたPortalにコンテンツを移動する場合:
createPortalTarget()
ユーティリティ関数を使用します
<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は、プラグインをインストールするときにアプリ内のすべてのコンポーネントにデフォルトインスタンスを提供しますが、必要に応じて独自のインスタンスを作成し、デフォルトインスタンスの代わりに使用できるようになりました。