过渡
Transition 组件在 Vue 内置的 transition 元素的基础上更进一步,让您可以从单个根组件协调嵌套的子过渡。
要开始使用,请通过 npm 安装无头 UI。
请注意,**此库仅支持 Vue 3**。
npm install @headlessui/vue
Vue 有一个内置的 <transition>
组件,它与 Tailwind 的基于类的样式化方法以及其他无头 UI 组件一起使用效果很好。实际上,您在本网站上找到的其他 Vue 组件的大多数演示和代码片段都专门依赖于此内置过渡。
但有一个例外:嵌套的子过渡。当您想要协调不同子元素的不同动画时,需要使用这种技术——例如,淡入对话框的背景,同时从屏幕一侧滑动进入对话框的内容。
使用内置的 <transition>
元素实现此效果的唯一方法是手动同步每个子过渡,即使如此,这种方法也可能存在错误和易出错。
这就是为什么我们在无头 UI 中包含一个 <TransitionRoot />
组件的原因。它的 API 与 Vue 自身的元素类似,但它还提供了一种通过包含的 <TransitionChild />
组件协调多个过渡的方法,如下所述。
对于除 Dialog
之外的所有组件,您可以使用 Vue 内置的 <transition>
元素,只要您应用单个过渡即可。要为 Dialog
设置动画,或协调任何其他组件上的多个过渡,请使用无头 UI 中的 TransitionRoot
组件。
TransitionRoot
接受一个 show
prop,用于控制是否应该显示或隐藏子元素,以及一组生命周期 prop(如 enter-from
和 leave-to
),这些 prop 允许您在过渡的特定阶段添加 CSS 类。
<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
prop 控制内容是否应该可见或隐藏。
<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
prop 将组件渲染为不同的元素或作为您自己的自定义组件。任何其他 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
将立即进入和离开,如果您使用此组件,这可能不是您想要的。
要为您的进入/离开过渡设置动画,请使用这些 prop 添加提供每个过渡阶段样式的类
- 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
),并在完成时淡入到完全不透明(opacity-100
)(即 enterTo
阶段)。
当元素被移除(leave
阶段)时,它将过渡不透明度属性,并花费 150 毫秒(transition-opacity duration-150
)。
它将从完全不透明开始(leave-from
阶段的 opacity-100
),并以完全透明结束(leave-to
阶段的 opacity-0
)。
所有这些 prop 都是可选的,并将默认设置为一个空字符串。
有时您需要使用不同的动画过渡多个元素,但所有这些动画都基于相同的状态。例如,假设用户单击一个按钮打开一个滑过屏幕的侧边栏,并且您还需要同时淡入背景叠加层。
您可以通过将相关的元素包装在一个父 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
组件与 TransitionRoot
组件具有完全相同的 API,但没有 show
prop,因为 show
值由父元素控制。
父 TransitionRoot
组件将始终自动等待所有子元素完成过渡,然后才会卸载,因此您无需自己管理任何时间安排。
如果您希望元素在第一次渲染时过渡,请将 appear
prop 设置为 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>
Prop | 默认值 | 描述 |
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 | 在离开过渡完成后发出。 |
Prop | 默认值 | 描述 |
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 | 在离开过渡完成后发出。 |