过渡

Transition 组件允许您使用 CSS 类来控制过渡的不同阶段的实际过渡样式,从而为条件渲染的元素添加进入/离开过渡。

要开始使用,请通过 npm 安装 Headless UI

npm install @headlessui/react

Transition 接受一个 show prop,该 prop 控制是否应该显示或隐藏子元素,以及一组生命周期 prop(如 enterFromleaveTo),这些 prop 允许您在过渡的特定阶段添加 CSS 类。

import { Transition } from '@headlessui/react' import { useState } from 'react' function MyComponent() { const [isShowing, setIsShowing] = useState(false) return ( <> <button onClick={() => setIsShowing((isShowing) => !isShowing)}> Toggle </button> <Transition show={isShowing} enter="transition-opacity duration-75" enterFrom="opacity-0" enterTo="opacity-100" leave="transition-opacity duration-150" leaveFrom="opacity-100" leaveTo="opacity-0" > I will fade in and out </Transition> </> ) }

将应该条件渲染的内容包装在 <Transition> 组件中,并使用 show prop 来控制内容是否应该可见或隐藏。

import { Transition } from '@headlessui/react' import { useState } from 'react' function MyComponent() { const [isShowing, setIsShowing] = useState(false) return ( <> <button onClick={() => setIsShowing((isShowing) => !isShowing)}>
Toggle
</button> <Transition show={isShowing}>I will appear and disappear.</Transition> </> ) }

默认情况下,过渡组件将渲染一个 div 元素。

使用 as prop 将组件渲染为不同的元素或您自己的自定义组件,确保您的自定义组件 转发 refs,以便 Headless UI 可以正确地连接一切。

import { forwardRef, useState, Fragment } from 'react' import { Dialog, Transition } from '@headlessui/react'
let MyDialogPanel = forwardRef(function (props, ref) {
return <Dialog.Panel className="" ref={ref} {...props} />
})
function MyDialog() { let [isOpen, setIsOpen] = useState(true) return ( <Transition
as={Dialog}
show={isOpen} onClose={() => setIsOpen(false)} >
<Transition.Child
as={MyDialogPanel}
enter="ease-out duration-300" enterFrom="opacity-0 scale-95" enterTo="opacity-100 scale-100" leave="ease-in duration-200" leaveFrom="opacity-100 scale-100" leaveTo="opacity-0 scale-95" >
<Dialog.Title>Deactivate account</Dialog.Title> {/* ... */} </Transition.Child> </Transition> ) }

默认情况下,Transition 将立即进入和离开,如果您使用此组件,这可能不是您想要的。

要为进入/离开过渡添加动画,请使用这些 prop 添加提供每个过渡阶段样式的类

  • enter: 在元素进入的整个过程中应用。通常您在此定义您的持续时间以及您想要过渡的属性,例如 transition-opacity duration-75
  • enterFrom: 进入的起点,例如,如果要淡入,则为 opacity-0
  • enterTo: 进入的终点,例如淡入后为 opacity-100
  • leave: 在元素离开的整个过程中应用。通常您在此定义您的持续时间以及您想要过渡的属性,例如 transition-opacity duration-75
  • leaveFrom: 离开的起点,例如,如果要淡出,则为 opacity-100
  • leaveTo: 离开的终点,例如淡出后为 opacity-0

以下是一个示例

import { Transition } from '@headlessui/react' import { useState } from 'react' function MyComponent() { const [isShowing, setIsShowing] = useState(false) return ( <> <button onClick={() => setIsShowing((isShowing) => !isShowing)}> Toggle </button>
<Transition
show={isShowing}
enter="transition-opacity duration-75"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="transition-opacity duration-150"
leaveFrom="opacity-100" leaveTo="opacity-0" > I will fade in and out </Transition> </> ) }

在此示例中,过渡元素将花费 75 毫秒进入(即 duration-75 类),并且将在该时间段内过渡不透明度属性(即 transition-opacity)。

它将从完全透明开始进入(即 enterFrom 阶段的 opacity-0),并在完成时淡入到完全不透明(opacity-100)(即 enterTo 阶段)。

当元素被移除(leave 阶段)时,它将过渡不透明度属性,并花费 150 毫秒来完成(transition-opacity duration-150)。

它将从完全不透明开始(leaveFrom 阶段的 opacity-100),并以完全透明结束(leaveTo 阶段的 opacity-0)。

所有这些 prop 都是可选的,并且默认情况下将只为空字符串。

有时您需要使用不同的动画过渡多个元素,但所有动画都基于相同的状态。例如,假设用户单击一个按钮来打开一个滑过屏幕的侧边栏,并且您还需要同时淡入一个背景叠加层。

您可以通过使用父 Transition 组件包装相关元素,并使用 Transition.Child 组件包装每个需要自身过渡样式的子元素来实现,Transition.Child 组件将自动与父 Transition 通信并继承父元素的 show 状态。

import { Transition } from '@headlessui/react' function Sidebar({ isShowing }) { return ( /* The `show` prop controls all nested `Transition.Child` components. */ <Transition show={isShowing}> {/* Background overlay */} <Transition.Child enter="transition-opacity ease-linear duration-300" enterFrom="opacity-0" enterTo="opacity-100" leave="transition-opacity ease-linear duration-300" leaveFrom="opacity-100" leaveTo="opacity-0" > {/* ... */} </Transition.Child> {/* Sliding sidebar */} <Transition.Child enter="transition ease-in-out duration-300 transform" enterFrom="-translate-x-full" enterTo="translate-x-0" leave="transition ease-in-out duration-300 transform" leaveFrom="translate-x-0" leaveTo="-translate-x-full" > {/* ... */} </Transition.Child> </Transition> ) }

Transition.Child 组件具有与 Transition 组件完全相同的 API,但没有 show prop,因为 show 值由父元素控制。

Transition 组件将始终自动等待所有子元素完成过渡后才卸载,因此您无需自己管理任何计时。

如果您希望元素在第一次渲染时过渡,请将 appear prop 设置为 true

如果您希望在页面初始加载时或其父元素被条件渲染时,某些元素过渡进来,这将很有用。

import { Transition } from '@headlessui/react' function MyComponent({ isShowing }) { return ( <Transition
appear={true}
show={isShowing} enter="transition-opacity duration-75" enterFrom="opacity-0" enterTo="opacity-100" leave="transition-opacity duration-150" leaveFrom="opacity-100" leaveTo="opacity-0" >
{/* Your content goes here*/} </Transition> ) }

Prop默认描述
show
布尔值

是否应该显示或隐藏子元素。

asdiv
字符串 | 组件

要渲染以代替 Transition 本身的元素或组件。

appearfalse
布尔值

是否应该在初始挂载时运行过渡。

unmounttrue
布尔值

根据 show 状态,元素是否应该被卸载或隐藏。

enter
字符串

在整个进入阶段向过渡元素添加的类。

enterFrom
字符串

在进入阶段开始之前向过渡元素添加的类。

enterTo
字符串

在进入阶段开始后立即向过渡元素添加的类。

entered
字符串

过渡完成后向过渡元素添加的类。这些类将在之后一直持续,直到离开的时候。

leave
字符串

在整个离开阶段向过渡元素添加的类。

leaveFrom
字符串

在离开阶段开始之前向过渡元素添加的类。

leaveTo
字符串

在离开阶段开始后立即向过渡元素添加的类。

beforeEnter
() => void

在我们开始进入过渡之前调用的回调函数。

afterEnter
() => void

在我们完成进入过渡后调用的回调函数。

beforeLeave
() => void

在我们开始离开过渡之前调用的回调函数。

afterLeave
() => void

在我们完成离开过渡后调用的回调函数。

Prop默认描述
asdiv
字符串 | 组件

要渲染以代替 Transition 本身的元素或组件。

appearfalse
布尔值

是否应该在初始挂载时运行过渡。

unmounttrue
布尔值

根据 show 状态,元素是否应该被卸载或隐藏。

enter
字符串

在整个进入阶段向过渡元素添加的类。

enterFrom
字符串

在进入阶段开始之前向过渡元素添加的类。

enterTo
字符串

在进入阶段开始后立即向过渡元素添加的类。

entered
字符串

过渡完成后向过渡元素添加的类。这些类将在之后一直持续,直到离开的时候。

leave
字符串

在整个离开阶段向过渡元素添加的类。

leaveFrom
字符串

在离开阶段开始之前向过渡元素添加的类。

leaveTo
字符串

在离开阶段开始后立即向过渡元素添加的类。

beforeEnter
() => void

在我们开始进入过渡之前调用的回调函数。

afterEnter
() => void

在我们完成进入过渡后调用的回调函数。

beforeLeave
() => void

在我们开始离开过渡之前调用的回调函数。

afterLeave
() => void

在我们完成离开过渡后调用的回调函数。

如果您有兴趣使用 Headless UI 和 Tailwind CSS 的预先设计的组件示例,请查看 **Tailwind UI** — 我们精心打造的一系列设计精美且精心制作的组件。

这是支持我们对像这样开源项目的努力的好方法,使我们能够改进它们并保持良好的维护。