Portal-Vue入門
PortalVueとは?
PortalVueは、コンポーネントのテンプレート(またはその一部)をドキュメント内の任意の場所にレンダリングできる2つのコンポーネントのセットです。Vueアプリによって制御される部分の外側にもレンダリングできます!
Vue 3の`Teleport`はどうですか?
良い質問です!ほとんどのシナリオでは、新しい`Teleport`コンポーネントがこのライブラリよりも優れた機能を提供するため、`portal-vue`は必要ない場合があります(つまり、注意点なしで)。
詳細な説明については、こちらをご覧ください。
セットアップ
パッケージのインストール
npm install --save portal-vue@next
# or with yarn
yarn add portal-vue@next
アプリケーションに追加する
import PortalVue from 'portal-vue'
import { createApp } from 'vue'
import App from './App.vue'
const app = createApp(App)
app.use(PortalVue)
app.mount('#app')
詳細なインストール手順、追加オプション、CDN経由のインストールについては、ドキュメントのインストールセクションを参照してください。
ブラウザのサポート
このプロジェクトは最新のJavaScript向けに構築されており、Vue自体も最新のブラウザをターゲットにしています。ESモジュールをサポートするすべてのブラウザ、つまり以下のブラウザをサポートしています。
- Chrome >=61
- Firefox >=60
- Safari >=11
- Edge >=16
何らかの理由で古いブラウザをサポートする必要がある場合は、`node_modules/portal-vue/dist`をbabelでトランスパイルするファイルのリストに含めてください。
Vue CLIは、`transpileDependencies`を使用して、このための専用オプションを提供しています。
// vue.config.js
module.exports = {
transpileDependencies: ['portal-vue']
}
使用方法
例について
以下の例には、ライブデモが含まれています。デモでは、1つのコンポーネント内でコンテンツを移動していますが、実際には`<portal-target>`はアプリ内のどこにでも配置できることに注意してください。
また、例のコードは単一ファイルコンポーネント形式( "`.vue`"ファイル)を使用しています。これについて詳しくない場合は、公式ドキュメントのこちらをご覧ください。
基本
<portal to="destination">
<p>This slot content will be rendered wherever the
<portal-target> with name 'destination'
is located.
</p>
</portal>
<portal-target name="destination">
<!--
This component can be located anywhere in your App.
The slot content of the above portal component will be rendered here.
-->
</portal-target>
ポータルの有効化/無効化
<portal to="destination" :disabled="true">
<p>
This slot content will be rendered right here as long as the `disabled` prop
evaluates to `true`,<br />
and will be rendered at the defined destination as when it is set to `false`
(which is the default).
</p>
</portal>
v-ifを使用した条件付きレンダリング
<portal to="destination" v-if="usePortal">
<ul>
<li>
When 'usePortal' evaluates to 'true', the portal's slot content will be
rendered at the destination.
</li>
<li>
When it evaluates to 'false', the content will be removed from the
destination
</li>
</ul>
</portal>
複数のポータル、1つのターゲット
`PortalTarget`コンポーネントには`multiple`モードがあり、複数の`Portal`コンポーネントからのコンテンツを*同時に*レンダリングできます。
コンテンツがレンダリングされる順序は、`Portal`コンポーネントの`order`プロップで調整できます。
<portal to="destination" :order="2">
<p>some content</p>
</portal>
<portal to="destination" :order="1">
<p>some other content</p>
</portal>
<div class="some-wrapper">
<portal-target name="destination" multiple />
</div>
結果
<div class="some-wrapper">
<p>some other content</p>
<p>some content</p>
</div>
ユースケース
モーダルとオーバーレイの配置
古いブラウザでは、`position: fixed`プロパティを持つ要素が、他の`position`値を持つノードツリーにネストされている場合、`position: fixed`は信頼できません。
しかし、通常、モーダル、ダイアログ、通知、スナックバー、および同様のUI要素などのコンポーネントを固定位置にレンダリングする必要があります。
また、DOMのどこかで要素を互いに重ねてレンダリングしようとすると、z-indexが問題になる可能性があります。
PortalVueを使用すると、モーダル/オーバーレイ/ドロップダウンコンポーネントを、ページの`body`の最後に配置できる`<portal-target>`にレンダリングできるため、スタイリングと配置がはるかに簡単になり、エラーが発生しにくくなります。
これで、コンポーネントを`position: absolute`で配置できます。
<body>
<div id="app" style="position: relative;">
<div>
<portal to="notification-outlet">
<notification style="position: absolute; top: 20px; right: 20px;">
This overlay can be positioned absolutely very easily.
</notification>
</portal>
</div>
<!-- rest of your app -->
</div>
<portal-target name="notification-outlet"></portal-target>
</body>
動的ウィジェットのレンダリング
Webサイトの小さな部分にVueを使用しているが、ページの反対側の場所に何かをレンダリングしたい場合は、PortalVueが役立ちます。
あなたのユースケースを教えてください!
ここで紹介したもの以外にもユースケースが見つかるはずです。Githubでissueを作成してご連絡ください。ここに掲載させていただきます。