Skip to content

wire:sort

Livewire 通过 wire:sortwire:sort:item 指令提供强大的拖放排序功能。使用这些工具,你可以使元素列表具有平滑动画的可排序性——所有这些都为你开箱即用。

基本用法

要使列表可排序,请将 wire:sort 添加到父元素并指定一个方法名来处理排序事件。然后,将 wire:sort:item 添加到每个具有唯一标识符的子元素。

以下是可排序待办事项列表的基本示例:

php
<?php

use Livewire\Component;
use Livewire\Attributes\Computed;

new class extends Component
{
    public Todo $todo;

    public function sortItem($item, $position)
    {
        $item = $this->todo->items()->findOrFail($item);

        // Update the item's position in the database and re-order other items...
    }
};
blade
<ul wire:sort="sortItem">
    @foreach ($todo->items as $item)
        <li wire:sort:item="{{ $item->id }}">
            {{ $item->title }}
        </li>
    @endforeach
</ul>

当用户将项目拖放到新位置时,Livewire 将使用两个参数调用你的 sortItem 方法:项目的唯一标识符(来自 wire:sort:item)和列表中新的从零开始的位置。

你负责在数据库中持久化新顺序。这通常涉及更新已移动项目的位置并调整其他受影响项目的位置。

跨组排序

如果页面上有多个可排序列表,并且希望允许用户在它们之间拖动项目,则可以使用 wire:sort:group 创建共享组。

通过为多个可排序容器分配相同的组名,可以将项目从一个列表拖动到另一个列表:

php
<?php

use Livewire\Component;
use Livewire\Attributes\Computed;

new class extends Component
{
    public User $user;

    public function sortItem($item, $position)
    {
        $item = $this->todo->items()->findOrFail($item);

        // Update the item's position in the database and re-order other items...
    }
};
blade
<div>
    @foreach ($user->todoLists as $todo)
        <ul wire:sort="sortItem" wire:sort:group="todos">
            @foreach ($todo->items as $item)
                <li wire:sort:item="{{ $item->id }}">
                    {{ $item->title }}
                </li>
            @endforeach
        </ul>
    @endforeach
</div>

当项目被拖动到不同的组时,只有目标组的处理程序将接收排序事件。你的处理程序需要检测项目属于不同的父级,将其与新的父模型重新关联,并更新旧父级和新父级项目的排序位置。

排序手柄

默认情况下,用户可以通过单击并拖动可排序元素上的任意位置来拖动项目。但是,你可以使用 wire:sort:handle 将拖动限制为特定手柄。

当你在可排序项目中有交互元素并希望防止意外拖动时,这很有用:

blade
<ul wire:sort="sortItem">
    @foreach ($todo->items as $item)
        <li wire:sort:item="{{ $item->id }}">
            <div wire:sort:handle>
                <!-- Drag icon... -->
            </div>

            {{ $item->title }}
        </li>
    @endforeach
</ul>

现在,用户只能通过单击并拖动标记为 wire:sort:handle 的元素来拖动项目。

忽略元素

你可以使用 wire:sort:ignore 防止可排序项目内的特定区域触发拖动操作。当你在可排序项目中有按钮或其他交互元素时,这特别有用:

blade
<ul wire:sort="sortItem">
    @foreach ($todo->items as $item)
        <li wire:sort:item="{{ $item->id }}">
            {{ $item->title }}

            <div wire:sort:ignore>
                <button type="button">Edit</button>
            </div>
        </li>
    @endforeach
</ul>

在标记为 wire:sort:ignore 的元素内单击和拖动将不起作用,允许用户与按钮和其他控件交互而不会意外触发排序操作。