过渡
Transition 组件允许您使用 CSS 类来控制过渡的不同阶段的实际过渡样式,从而为条件渲染的元素添加进入/离开过渡。
要开始使用,请通过 npm 安装 Headless UI
npm install @headlessui/react
Transition
接受一个 show
prop,该 prop 控制是否应该显示或隐藏子元素,以及一组生命周期 prop(如 enterFrom
和 leaveTo
),这些 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 ( <Transitionas={Dialog}show={isOpen} onClose={() => setIsOpen(false)} > <Transition.Childas={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>
<Transitionshow={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 | — | 布尔值 是否应该显示或隐藏子元素。 |
as | div | 字符串 | 组件 要渲染以代替 Transition 本身的元素或组件。 |
appear | false | 布尔值 是否应该在初始挂载时运行过渡。 |
unmount | true | 布尔值 根据 show 状态,元素是否应该被卸载或隐藏。 |
enter | — | 字符串 在整个进入阶段向过渡元素添加的类。 |
enterFrom | — | 字符串 在进入阶段开始之前向过渡元素添加的类。 |
enterTo | — | 字符串 在进入阶段开始后立即向过渡元素添加的类。 |
entered | — | 字符串 过渡完成后向过渡元素添加的类。这些类将在之后一直持续,直到离开的时候。 |
leave | — | 字符串 在整个离开阶段向过渡元素添加的类。 |
leaveFrom | — | 字符串 在离开阶段开始之前向过渡元素添加的类。 |
leaveTo | — | 字符串 在离开阶段开始后立即向过渡元素添加的类。 |
beforeEnter | — | () => void 在我们开始进入过渡之前调用的回调函数。 |
afterEnter | — | () => void 在我们完成进入过渡后调用的回调函数。 |
beforeLeave | — | () => void 在我们开始离开过渡之前调用的回调函数。 |
afterLeave | — | () => void 在我们完成离开过渡后调用的回调函数。 |
Prop | 默认 | 描述 |
as | div | 字符串 | 组件 要渲染以代替 Transition 本身的元素或组件。 |
appear | false | 布尔值 是否应该在初始挂载时运行过渡。 |
unmount | true | 布尔值 根据 show 状态,元素是否应该被卸载或隐藏。 |
enter | — | 字符串 在整个进入阶段向过渡元素添加的类。 |
enterFrom | — | 字符串 在进入阶段开始之前向过渡元素添加的类。 |
enterTo | — | 字符串 在进入阶段开始后立即向过渡元素添加的类。 |
entered | — | 字符串 过渡完成后向过渡元素添加的类。这些类将在之后一直持续,直到离开的时候。 |
leave | — | 字符串 在整个离开阶段向过渡元素添加的类。 |
leaveFrom | — | 字符串 在离开阶段开始之前向过渡元素添加的类。 |
leaveTo | — | 字符串 在离开阶段开始后立即向过渡元素添加的类。 |
beforeEnter | — | () => void 在我们开始进入过渡之前调用的回调函数。 |
afterEnter | — | () => void 在我们完成进入过渡后调用的回调函数。 |
beforeLeave | — | () => void 在我们开始离开过渡之前调用的回调函数。 |
afterLeave | — | () => void 在我们完成离开过渡后调用的回调函数。 |