Skip to content
全部文档

wire:sort

Livewire 通过 wire:sort 指令提供拖放排序。把它加到父元素上,并在每个子元素上使用 wire:sort:item,即可开箱即用地实现带流畅动画的可排序列表。

基本用法

要让列表可排序,给父元素加上带处理函数名的 wire:sort,并给每个子元素加上带唯一标识的 wire:sort:item

php
<?php

use Livewire\Component;

new class extends Component {
    public TodoList $list;

    public function handleSort($id, $position)
    {
        $task = $this->list->tasks()->findOrFail($id);

        // Update the task's position and re-order other tasks...
    }
};
blade
<ul wire:sort="handleSort">
    @foreach ($list->tasks as $task)
        <li wire:key="{{ $task->id }}" wire:sort:item="{{ $task->id }}">
            {{ $task->title }}
        </li>
    @endforeach
</ul>

用户把某项拖放到新位置时,Livewire 会用两个参数调用你的处理函数:该项的标识(来自 wire:sort:item)以及新的从零开始的位置。

你需要负责把新顺序持久化到数据库。

跨组排序

要允许在多个列表之间拖拽项目,在每个容器上使用相同组名的 wire:sort:group

要识别项目被放到哪个组,给每个容器加上 wire:sort:group-id。其值会作为第三个参数传给你的处理函数:

php
<?php

use Livewire\Component;
use Livewire\Attributes\Computed;
use App\Models\Card;

new class extends Component {
    public Board $board;

    #[Computed]
    public function columns()
    {
        return $this->board->columns;
    }

    public function handleSort($id, $position, $columnId)
    {
        $card = $this->board->cards()->findOrFail($id);

        // Update the card's position and re-order other cards...
    }
};
blade
<div>
    @foreach ($this->columns as $column)
        <ul wire:sort="handleSort" wire:sort:group="cards" wire:sort:group-id="{{ $column->id }}">
            @foreach ($column->cards as $card)
                <li wire:key="{{ $card->id }}" wire:sort:item="{{ $card->id }}">
                    {{ $card->title }}
                </li>
            @endforeach
        </ul>
    @endforeach
</div>

项目被拖到另一组时,只有目标组的处理函数会触发。

排序手柄

默认情况下,用户点击项目任意处即可拖拽。若要限制只能通过特定手柄拖拽,使用 wire:sort:handle

blade
<ul wire:sort="handleSort">
    @foreach ($list->tasks as $task)
        <li wire:key="{{ $task->id }}" wire:sort:item="{{ $task->id }}">
            <div wire:sort:handle>
                <!-- Drag icon... -->
            </div>

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

现在用户只能从手柄元素开始拖拽。

忽略元素

要防止特定区域触发拖拽操作,使用 wire:sort:ignore。这对可排序项内的按钮或其他交互元素很有用:

blade
<ul wire:sort="handleSort">
    @foreach ($list->tasks as $task)
        <li wire:key="{{ $task->id }}" wire:sort:item="{{ $task->id }}">
            {{ $task->title }}

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

参考

blade
wire:sort="method"
wire:sort:item="id"
wire:sort:group="name"
wire:sort:group-id="identifier"
wire:sort:handle
wire:sort:ignore

该指令没有修饰符。