コンテンツに移動する
先頭へ戻る
このページの内容

高度な利用

ターゲットとソースの切り替え

<portal>to プロップと <portal-target>name プロップは v-bind を使って動的に変更できます。これにより、1 つの <portal> のコンテンツを別の <portal-target> に送信したり、<portal-target> のソースを 1 つの <portal> から別の <portal> に切り替えたりできます。

html
<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 に送信して、スロット コンテンツにプロップを提供できます。

html
<portal to="destination" v-slot="{ message }">
  <p>{{message}}</p>
</portal>

<portal-target
  name="destination"
  :slot-props="{message: 'Hello from the Target to You!'}"
/>

結果

html
<!-- rendered in the target location-->
<p>Hello from the Target to You!</p>

トランジション

Portal トランジション

<portal> にトランジションを渡しても問題ありません。コンテンツが <portal-target> でレンダリングされるときと同じように動作します。

html
<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 トランジション

html
<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> を使用した別の例を次に示します。

html
<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 を導入して、使用シナリオを制限