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-fromleave-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
ブール値

子要素を表示または非表示にするかどうか。

asdiv
文字列 | コンポーネント

Transition自体に代えてレンダリングする要素またはコンポーネント。

appearfalse
ブール値

初期マウント時にトランジションを実行するかどうか。

unmounttrue
ブール値

show状態に基づいて要素をアンマウントするか、非表示にするか。

enter
文字列

表示フェーズ全体でトランジション要素に追加するクラス。

enter-from
文字列

表示フェーズの開始前にトランジション要素に追加するクラス。

enter-to
文字列

表示フェーズの開始直後にトランジション要素に追加するクラス。

entered
文字列

トランジションが完了したらトランジション要素に追加するクラス。これらのクラスはその後、非表示になるまで保持されます。

leave
文字列

非表示フェーズ全体でトランジション要素に追加するクラス。

leave-from
文字列

非表示フェーズの開始前にトランジション要素に追加するクラス。

leave-to
文字列

非表示フェーズの開始直後にトランジション要素に追加するクラス。

イベント説明
before-enter

表示トランジションの開始前に発信されます。

after-enter

表示トランジションの完了後に発信されます。

before-leave

非表示トランジションの開始前に発信されます。

after-leave

非表示トランジションの完了後に発信されます。

プロパティデフォルト説明
asdiv
文字列 | コンポーネント

Transition自体に代えてレンダリングする要素またはコンポーネント。

appearfalse
ブール値

初期マウント時にトランジションを実行するかどうか。

unmounttrue
ブール値

show状態に基づいて要素をアンマウントするか、非表示にするか。

enter
文字列

表示フェーズ全体でトランジション要素に追加するクラス。

enter-from
文字列

表示フェーズの開始前にトランジション要素に追加するクラス。

enter-to
文字列

表示フェーズの開始直後にトランジション要素に追加するクラス。

entered
文字列

トランジションが完了したらトランジション要素に追加するクラス。これらのクラスはその後、非表示になるまで保持されます。

leave
文字列

非表示フェーズ全体でトランジション要素に追加するクラス。

leave-from
文字列

非表示フェーズの開始前にトランジション要素に追加するクラス。

leave-to
文字列

非表示フェーズの開始直後にトランジション要素に追加するクラス。

イベント説明
before-enter

表示トランジションの開始前に発信されます。

after-enter

表示トランジションの完了後に発信されます。

before-leave

非表示トランジションの開始前に発信されます。

after-leave

非表示トランジションの完了後に発信されます。

Headless UIとTailwind CSSを使用した、事前にデザインされたコンポーネントの例に興味がある場合は、Tailwind UIをご覧ください。これは、私たちが作成した、美しくデザインされ、専門的に作られたコンポーネントのコレクションです。

これは、このようなオープンソースプロジェクトへの私たちの取り組みをサポートする素晴らしい方法であり、それらを改善し、維持し続けることを可能にします。