高度な利用
ターゲットとソースの切り替え
<portal>
の to
プロップと <portal-target>
の name
プロップは v-bind
を使って動的に変更できます。これにより、1 つの <portal>
のコンテンツを別の <portal-target>
に送信したり、<portal-target>
のソースを 1 つの <portal>
から別の <portal>
に切り替えたりできます。
<portal v-bind:to="name">
Content will be dynamically sent to the destination that `name` evaluates to
</portal>
<portal-target v-bind:name="name">
by changing the 'name', you can define which portal's content should be shown.
</portal-target>
スコープ付きスロット
PortalVue は スコープ付きスロット と併用することもできます。これにより、スコープ付きスロットを PortalTarget に送信して、スロット コンテンツにプロップを提供できます。
<portal to="destination" v-slot="{ message }">
<p>{{message}}</p>
</portal>
<portal-target
name="destination"
:slot-props="{message: 'Hello from the Target to You!'}"
/>
結果
<!-- rendered in the target location-->
<p>Hello from the Target to You!</p>
トランジション
Portal トランジション
<portal>
にトランジションを渡しても問題ありません。コンテンツが <portal-target>
でレンダリングされるときと同じように動作します。
<portal to="destination">
<transition name="fade">
<p v-if="hasMessages" key="1">You have {{messages.length}} new messages</p>
<p v-else key="2">No unread messages</p>
</transition>
</portal>
ただし、複数の <portal>
に 1 つの <portal-target>
を使用する場合、ターゲット側でトランジションを定義する必要があります。これもサポートされています。
PortalTarget トランジション
<portal-target name="target">
<template v-slot:default="nodes">
<transition name="fade" mode="out-in">
<component :is="nodes[0]" />
</transition>
</template>
</portal-target>
PortalVue 3.0
では、Target のトランジションが再設計されました。新しい構文は少し冗長で、ハックっぽい感じがしますが、Vue の v-slot 構文を有効活用したもので、PortalVue 2.*
で発生していたターゲット トランジションの厄介なエッジケースを解消するために必要でした。
基本的に、「wrapper」という名前のスロットにトランジションを渡し、スロット プロップから nodes
という配列を取得します。
Vue の <component :is="">
を使用して、それらをトランジションのコンテンツに変換できます。
代わりに <transition-group>
を使用した別の例を次に示します。
<portal-target name="target">
<template #default="nodes">
<transition-group name="fade">
<component :is="node" v-for="node in nodes" :key="node" />
</transition-group>
</template>
</portal-target>
適切な名前空間
コンテンツを Portals
から PortalTargets
に移動するには、2 つを連携させるためのいくつかの仲介状態管理が必要です。これを「ワームホール」と呼んでいます。
PortalVue <=2.*
では、このワームホールはシングルトン インスタンスでしたが、その結果、to
プロパティと name
プロパティの名前空間もグローバルになりました。
PortalVue 3.0
では引き続きデフォルトのワームホールを使用しますが、独自のワームホール インスタンスを作成してアプリのさまざまな領域にあるポータル コンポーネントに提供したり、同じページに配置した異なるアプリに提供したりすることもサポートされています。
これにより、名前の競合がいくらか起こりにくくなります。特に、プロジェクトで使用しているサードパーティ製のライブラリが、ユーザーの知らないうちにポータル vue を使用して要素を移動している場合も同様です。
では、どのように機能するでしょうか。
TODO: createWormhole()
の使用についての適切なドキュメント
Vue アプリ外でレンダリング
TODO: createPortalTarget
を導入して、使用シナリオを制限