Transition
Transitionコンポーネントは、Vueの組み込みトランジション要素をさらに一歩進めて、単一のルートコンポーネントからネストされた子トランジションを調整できるようにします。
はじめに、npm経由でHeadless UIをインストールします。
このライブラリはVue 3のみサポートしている点にご注意ください。
npm install @headlessui/vue
Vueには、Tailwindのクラスベースのスタイルアプローチと、他のHeadless UIコンポーネントと併用して優れた機能を発揮する組み込みの<transition>
コンポーネントがあります。実際、このサイトにある他のVueコンポーネントのほとんどのデモとコードスニペットは、この組み込みのトランジションにのみ依存しています。
しかし、1つの例外があります。それは、ネストされた子トランジションです。このテクニックは、異なる子要素に対して異なるアニメーションを調整する場合(たとえば、ダイアログの背景をフェードインしながら、同時にダイアログの内容を画面の片側からスライドインするなど)に必要になります。
組み込みの<transition>
要素を使用してこの効果を実現する唯一の方法は、各子トランジションを手動で同期することですが、それでもそのアプローチはバグが発生しやすく、エラーが発生しやすい可能性があります。
そのため、Headless UIに<TransitionRoot />
コンポーネントを含めました。そのAPIはVue独自の要素に似ていますが、以下で説明するように、付属の<TransitionChild />
コンポーネントを介して複数のトランジションを調整する手段も提供します。
Dialog
を除くすべてのコンポーネントでは、単一のトランジションを適用する場合は、Vueの組み込み<transition>
要素を使用できます。Dialog
をアニメーション化する場合、または他のコンポーネントで複数のトランジションを調整する場合は、代わりにHeadless UIのTransitionRoot
コンポーネントを使用してください。
TransitionRoot
は、子要素の表示または非表示を制御するshow
プロップと、トランジションの特定のフェーズでCSSクラスを追加できるライフサイクルプロップ(enter-from
やleave-to
など)を受け入れます。
<template> <button @click="isShowing = !isShowing">Toggle</button> <TransitionRoot :show="isShowing" enter="transition-opacity duration-75" enter-from="opacity-0" enter-to="opacity-100" leave="transition-opacity duration-150" leave-from="opacity-100" leave-to="opacity-0" > I will fade in and out </TransitionRoot> </template> <script setup> import { ref } from 'vue' import { TransitionRoot } from '@headlessui/vue' const isShowing = ref(true) </script>
条件付きでレンダリングするコンテンツを<TransitionRoot>
コンポーネントでラップし、show
プロップを使用してコンテンツを表示または非表示にするかを制御します。
<template> <button @click="isShowing = !isShowing">Toggle</button>
<TransitionRoot :show="isShowing">I will appear and disappear. </TransitionRoot> </template> <script setup> import { ref } from 'vue' import { TransitionRoot } from '@headlessui/vue' const isShowing = ref(true) </script>
デフォルトでは、トランジションコンポーネントはdiv
要素をレンダリングします。
as
プロップを使用して、コンポーネントを別の要素または独自のカスタムコンポーネントとしてレンダリングします。他のHTML属性(class
など)は、通常の要素と同じようにTransitionRoot
に直接追加できます。
<template> <button @click="isShowing = !isShowing">Toggle</button>
<TransitionRoot :show="isShowing" as="a" href="/my-url" class="font-bold">I will appear and disappear. </TransitionRoot> </template> <script setup> import { ref } from 'vue' import { TransitionRoot } from '@headlessui/vue' const isShowing = ref(true) </script>
デフォルトでは、TransitionRoot
は瞬時に表示と非表示を切り替えますが、このコンポーネントを使用する場合は、それが目的ではない可能性があります。
表示/非表示のトランジションをアニメーション化するには、これらのプロップを使用して、トランジションの各フェーズのスタイルを提供するクラスを追加します。
- enter: 要素が表示されている間ずっと適用されます。通常、ここでは期間と、遷移させたいプロパティを定義します。たとえば、
transition-opacity duration-75
など。 - enter-from: 表示開始点。たとえば、フェードインする場合は
opacity-0
。 - enter-to: 表示終了点。たとえば、フェードイン後の
opacity-100
。 - leave: 要素が非表示になっている間ずっと適用されます。通常、ここでは期間と、遷移させたいプロパティを定義します。たとえば、
transition-opacity duration-75
など。 - leave-from: 非表示開始点。たとえば、フェードアウトする場合は
opacity-100
。 - leave-to: 非表示終了点。たとえば、フェードアウト後の
opacity-0
。
例を以下に示します。
<template> <button @click="isShowing = !isShowing">Toggle</button> <TransitionRoot :show="isShowing"
enter="transition-opacity duration-75"enter-from="opacity-0"enter-to="opacity-100"leave="transition-opacity duration-150"leave-from="opacity-100"leave-to="opacity-0"> I will appear and disappear. </TransitionRoot> </template> <script setup> import { ref } from 'vue' import { TransitionRoot } from '@headlessui/vue' const isShowing = ref(true) </script>
この例では、トランジション要素は表示に75ミリ秒かかり(duration-75
クラス)、その間に不透明度プロパティが遷移します(transition-opacity
)。
表示開始時は完全に透明になり(enter-from
フェーズのopacity-0
)、完了時に完全に不透明になります(enterTo
フェーズのopacity-100
)。
要素が削除されるとき(leave
フェーズ)、不透明度プロパティが遷移し、150ミリ秒かかります(transition-opacity duration-150
)。
開始時は完全に不透明(leave-from
フェーズのopacity-100
)、終了時は完全に透明になります(leave-to
フェーズのopacity-0
)。
これらのプロップはすべてオプションであり、デフォルトは空文字列になります。
場合によっては、異なるアニメーションで複数の要素をトランジションする必要がありますが、すべて同じ状態に基づいています。たとえば、ユーザーがボタンをクリックして画面上にスライドするサイドバーを開き、同時に背景オーバーレイをフェードインする必要があるとします。
これを行うには、関連する要素を親TransitionRoot
コンポーネントでラップし、独自のトランジションスタイルが必要な各子をTransitionChild
コンポーネントでラップします。これにより、親TransitionRoot
と自動的に通信し、親のshow
状態を継承します。
<template> <!-- The `show` prop controls all nested `TransitionChild` components. --> <TransitionRoot :show="isShowing"> <!-- Background overlay --> <TransitionChild enter="transition-opacity ease-linear duration-300" enter-from="opacity-0" enter-to="opacity-100" leave="transition-opacity ease-linear duration-300" leave-from="opacity-100" leave-to="opacity-0" > <!-- ... --> </TransitionChild> <!-- Sliding sidebar --> <TransitionChild enter="transition ease-in-out duration-300 transform" enter-from="-translate-x-full" enter-to="translate-x-0" leave="transition ease-in-out duration-300 transform" leave-from="translate-x-0" leave-to="-translate-x-full" > <!-- ... --> </TransitionChild> </TransitionRoot> </template> <script setup> import { ref } from 'vue' import { TransitionRoot, TransitionChild } from '@headlessui/vue' const isShowing = ref(true) </script>
TransitionChild
コンポーネントのAPIはTransitionRoot
コンポーネントとまったく同じですが、show
値は親によって制御されるため、show
プロップはありません。
親TransitionRoot
コンポーネントは、アンマウントする前に常にすべての子のトランジションが完了するのを自動的に待機するため、タイミングを自分で管理する必要はありません。
要素を最初にレンダリングしたときにトランジションさせたい場合は、appear
プロップをtrue
に設定します。
これは、最初のページ読み込み時、または親が条件付きでレンダリングされるときに、何かをトランジションインさせたい場合に役立ちます。
<template> <TransitionRoot
appear:show="isShowing" enter="transition-opacity duration-75" enter-from="opacity-0" enter-to="opacity-100" leave="transition-opacity duration-150" leave-from="opacity-100" leave-to="opacity-0" > <!-- Your content goes here --> </TransitionRoot> </template> <script setup> import { ref } from 'vue' import { TransitionRoot } from '@headlessui/vue' const isShowing = ref(true) </script>
プロパティ | デフォルト | 説明 |
show | — | ブール値 子要素を表示または非表示にするかどうか。 |
as | div | 文字列 | コンポーネント Transition自体に代えてレンダリングする要素またはコンポーネント。 |
appear | false | ブール値 初期マウント時にトランジションを実行するかどうか。 |
unmount | true | ブール値 show状態に基づいて要素をアンマウントするか、非表示にするか。 |
enter | — | 文字列 表示フェーズ全体でトランジション要素に追加するクラス。 |
enter-from | — | 文字列 表示フェーズの開始前にトランジション要素に追加するクラス。 |
enter-to | — | 文字列 表示フェーズの開始直後にトランジション要素に追加するクラス。 |
entered | — | 文字列 トランジションが完了したらトランジション要素に追加するクラス。これらのクラスはその後、非表示になるまで保持されます。 |
leave | — | 文字列 非表示フェーズ全体でトランジション要素に追加するクラス。 |
leave-from | — | 文字列 非表示フェーズの開始前にトランジション要素に追加するクラス。 |
leave-to | — | 文字列 非表示フェーズの開始直後にトランジション要素に追加するクラス。 |
イベント | 説明 |
before-enter | 表示トランジションの開始前に発信されます。 |
after-enter | 表示トランジションの完了後に発信されます。 |
before-leave | 非表示トランジションの開始前に発信されます。 |
after-leave | 非表示トランジションの完了後に発信されます。 |
プロパティ | デフォルト | 説明 |
as | div | 文字列 | コンポーネント Transition自体に代えてレンダリングする要素またはコンポーネント。 |
appear | false | ブール値 初期マウント時にトランジションを実行するかどうか。 |
unmount | true | ブール値 show状態に基づいて要素をアンマウントするか、非表示にするか。 |
enter | — | 文字列 表示フェーズ全体でトランジション要素に追加するクラス。 |
enter-from | — | 文字列 表示フェーズの開始前にトランジション要素に追加するクラス。 |
enter-to | — | 文字列 表示フェーズの開始直後にトランジション要素に追加するクラス。 |
entered | — | 文字列 トランジションが完了したらトランジション要素に追加するクラス。これらのクラスはその後、非表示になるまで保持されます。 |
leave | — | 文字列 非表示フェーズ全体でトランジション要素に追加するクラス。 |
leave-from | — | 文字列 非表示フェーズの開始前にトランジション要素に追加するクラス。 |
leave-to | — | 文字列 非表示フェーズの開始直後にトランジション要素に追加するクラス。 |
イベント | 説明 |
before-enter | 表示トランジションの開始前に発信されます。 |
after-enter | 表示トランジションの完了後に発信されます。 |
before-leave | 非表示トランジションの開始前に発信されます。 |
after-leave | 非表示トランジションの完了後に発信されます。 |