You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel Livewire拖拽排序无法触发更新方法问题求助

Laravel Livewire 拖拽排序无法触发后端方法问题

问题背景

在Laravel/Livewire项目中实现拖拽排序功能时,拖拽仅显示受限效果,updateSocialMediaOrder方法始终未被调用,多浏览器测试均存在该问题,控制台无报错信息。

相关代码

组件文件(app/Livewire/Admin/SocialMediasEditor.php)

<?php

namespace App\Livewire\Admin;

use App\Models\SocialMedia;
use Livewire\Component;

class SocialMediasEditor extends Component
{
    public $socialMedias = [];

    public function render()
    {
        $this->socialMedias = SocialMedia::query()->orderBy('order')->get();
        return view('livewire.admin.social-medias-editor');
    }

    public function updateSocialMediaOrder($socialMedias)
    {
        dd($socialMedias);
        foreach ($socialMedias as $socialMedia) {
            SocialMedia::whereId($socialMedia['value'])->update(['order' => $socialMedia['order']]);
        }
    }

    public function removeSocialMedia($id)
    {
        SocialMedia::whereId($id)->delete();
    }
}

模板文件(livewire/admin/social-medias-editor.blade.php)

<div id="social_medias_editor_admin_page_container">
    <div class="shadow-xl rounded p-10 w-[40%] mx-auto">
        <ul wire:sortable="updateSocialMediaOrder" >
            @foreach ($socialMedias as $socialMedia)
                <li wire:sortable.item="{{ $socialMedia->id }}" wire:key="social-media-{{ $socialMedia->id }}"
                    class="flex justify-between cursor-col-resize ">
                    <div class="my-4 w-full flex justify-between p-3">
                        <span wire:sortable.handle class="flex cursor-pointer">
                            {{ $socialMedia->id }}=>{{ $socialMedia->name }}
                        </span>
                        <button wire:click="removeSocialMedia({{ $socialMedia->id }})">Remove</button>
                    </div>
                </li>
           @endforeach
        </ul>
    </div>
</div>

布局文件中JS引入部分

...
@livewireScripts
@stack('scripts')
@livewire('wire-elements-modal')

<script src="https://cdn.jsdelivr.net/gh/livewire/sortable@v1.x.x/dist/livewire-sortable.js"></script>

</body>
</html>

项目环境版本

"laravel/framework": "^10.48.7",
"tailwindcss": "^3.4.1",
"livewire/livewire": "^3.4.10",

解决方案

1. 移除不兼容的Sortable JS文件

Livewire 3已内置Sortable功能,无需引入针对Livewire 2的第三方livewire-sortable.js,直接删除布局文件中的上述JS引入代码。

2. 修正组件数据加载逻辑

将render方法中的数据库查询移至mount方法,避免每次组件渲染都重复查询,同时更新排序方法逻辑:

<?php

namespace App\Livewire\Admin;

use App\Models\SocialMedia;
use Livewire\Component;

class SocialMediasEditor extends Component
{
    public $socialMedias = [];

    public function mount()
    {
        // 仅在组件初始化时加载数据
        $this->socialMedias = SocialMedia::orderBy('order')->get();
    }

    public function render()
    {
        return view('livewire.admin.social-medias-editor');
    }

    public function updateSocialMediaOrder($items)
    {
        // 遍历排序后的数组,更新数据库中的order字段
        foreach ($items as $index => $item) {
            SocialMedia::whereId($item['value'])->update(['order' => $index + 1]);
        }
        // 重新加载数据同步前端显示
        $this->socialMedias = SocialMedia::orderBy('order')->get();
    }

    public function removeSocialMedia($id)
    {
        SocialMedia::whereId($id)->delete();
        // 删除后重新加载数据
        $this->socialMedias = SocialMedia::orderBy('order')->get();
    }
}

3. 调整模板中的Sortable指令与样式

确保指令符合Livewire 3规范,优化样式避免拖拽被干扰:

<div id="social_medias_editor_admin_page_container">
    <div class="shadow-xl rounded p-10 w-[40%] mx-auto">
        <ul wire:sortable="updateSocialMediaOrder" class="space-y-2">
            @foreach ($socialMedias as $socialMedia)
                <li wire:sortable.item="{{ $socialMedia->id }}" wire:key="social-media-{{ $socialMedia->id }}"
                    class="flex justify-between items-center p-3 bg-gray-50 rounded">
                    <span wire:sortable.handle class="flex items-center cursor-grab active:cursor-grabbing">
                        ☰ {{ $socialMedia->id }}=>{{ $socialMedia->name }}
                    </span>
                    <button wire:click="removeSocialMedia({{ $socialMedia->id }})" class="text-red-600">Remove</button>
                </li>
           @endforeach
        </ul>
    </div>
</div>

4. 验证数据库字段

确认social_medias表存在order字段,类型为整数(如unsigned int),并设置合理默认值(如0)。


内容的提问来源于stack exchange,提问作者Petro Gromovo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 20:24:52