Skip to content
全部文档

wire:transition

wire:transition 利用浏览器原生的 View Transitions API,在元素出现、消失或变更时启用流畅动画。

与基于 JavaScript 的动画库不同,View Transitions 由浏览器原生处理并硬件加速,因而动画更流畅、开销更小。

基本用法

给在 Livewire 更新期间可能被添加、移除或更改的任意元素加上 wire:transition

php
class ShowPost extends Component
{
    public Post $post;

    public $showComments = false;
}
blade
<div>
    <button wire:click="$toggle('showComments')">Toggle comments</button>

    @if ($showComments)
        <div wire:transition> <!-- [tl! highlight] -->
            @foreach ($post->comments as $comment)
                <div>{{ $comment->body }}</div>
            @endforeach
        </div>
    @endif
</div>

评论出现或消失时,浏览器会平滑地交叉淡入淡出,而不是突然显示或隐藏。

命名过渡

默认情况下,Livewire 会给带有 wire:transition 的元素分配 view-transition-name match-element。你可以提供自定义名称以启用更高级的过渡效果:

blade
<div wire:transition="sidebar">...</div>

这会将该元素的 view-transition-name CSS 属性设为 sidebar,你可用 CSS 定位它以自定义动画。

用 CSS 自定义动画

View Transitions 完全通过 CSS 控制。你可以通过定位 view-transition 伪元素来自定义动画:

css
/* Customize the transition for a specific element */
::view-transition-old(sidebar) {
    animation: 300ms ease-out both slide-out;
}

::view-transition-new(sidebar) {
    animation: 300ms ease-in both slide-in;
}

@keyframes slide-out {
    to { transform: translateX(-100%); }
}

@keyframes slide-in {
    from { transform: translateX(100%); }
}

View Transitions API 提供了三个可样式化的伪元素:

  • ::view-transition-old(name)离开元素的快照
  • ::view-transition-new(name)进入元素的快照
  • ::view-transition-group(name)两个快照的容器

过渡类型

对于步骤向导等需要按方向使用不同动画的复杂场景,可以使用过渡类型。这样你可以对「前进」和「后退」使用不同动画。

使用 $this->transition() 方法设置过渡类型:

php
class Wizard extends Component
{
    public $step = 1;

    public function goToStep($step)
    {
        $this->transition(type: $step > $this->step ? 'forward' : 'backward');

        $this->step = $step;
    }
}

然后在 CSS 中用 :active-view-transition-type() 选择器定位该类型:

css
html:active-view-transition-type(forward) {
    &::view-transition-old(content) {
        animation: 300ms ease-out both slide-out-left;
    }
    &::view-transition-new(content) {
        animation: 300ms ease-in both slide-in-right;
    }
}

html:active-view-transition-type(backward) {
    &::view-transition-old(content) {
        animation: 300ms ease-out both slide-out-right;
    }
    &::view-transition-new(content) {
        animation: 300ms ease-in both slide-in-left;
    }
}

@keyframes slide-out-left {
    from { transform: translateX(0); opacity: 1; }
    to { transform: translateX(-100%); opacity: 0; }
}

@keyframes slide-in-right {
    from { transform: translateX(100%); opacity: 0; }
    to { transform: translateX(0); opacity: 1; }
}

@keyframes slide-out-right {
    from { transform: translateX(0); opacity: 1; }
    to { transform: translateX(100%); opacity: 0; }
}

@keyframes slide-in-left {
    from { transform: translateX(-100%); opacity: 0; }
    to { transform: translateX(0); opacity: 1; }
}

对于始终朝同一方向过渡的方法,可以改用 #[Transition] 属性:

php
use Livewire\Attributes\Transition;

class Wizard extends Component
{
    public $step = 1;

    #[Transition(type: 'forward')]
    public function next()
    {
        $this->step++;
    }

    #[Transition(type: 'backward')]
    public function previous()
    {
        $this->step--;
    }
}

带类型交换期间的未命名过渡

当带类型的过渡处于活动状态时,Livewire 将交换视为一个统一编排的单元。该交换内任何未命名wire:transition 元素保持未命名,并随其父级快照一起过渡,而不会成为带有浏览器默认淡入淡出的独立组。

blade
<div wire:transition="slide">
    <p>Step content</p>

    {{-- Unnamed: rides along with the parent's "slide" during a typed swap --}}
    <div wire:transition>
        <button>Save</button>
    </div>
</div>

若需要内部元素在带类型交换期间独立动画,请为其指定明确名称:

blade
<div wire:transition="badge">...</div>

在带类型过渡之外(常规 morph,例如验证错误出现时),未命名的 wire:transition 元素仍使用 match-element,并像以前一样独立动画。

跳过过渡

有时你可能希望对特定操作禁用过渡——例如,「reset」按钮应瞬间跳到第一步且无动画。

使用 $this->skipTransition() 可在当前请求中禁用过渡:

php
public function reset()
{
    $this->skipTransition();

    $this->step = 1;
}

或使用带有 skip: true#[Transition] 属性:

php
use Livewire\Attributes\Transition;

#[Transition(skip: true)]
public function reset()
{
    $this->step = 1;
}

尊重减少动效偏好

Livewire 会自动尊重用户的 prefers-reduced-motion 设置。启用时会禁用过渡,以免给对动效敏感的用户带来不适。

浏览器支持

View Transitions 支持 Chrome 111+、Edge 111+ 和 Safari 18+。在不支持 View Transitions 的浏览器中,元素会无动画地出现和消失——功能仍可用,只是没有视觉过渡。

WARNING

Firefox 支持有限

Firefox 144+ 支持基本的 view transitions,但不支持过渡类型。

View browser support on caniuse.com →

另见

参考

blade
wire:transition="name"
表达式说明
(无)使用 match-element 作为 view-transition-name
"name"使用所提供的字符串作为 view-transition-name

此指令没有修饰符。