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

Laravel排序集合传递至Vue后排序失效问题排查与解决

问题

我在Laravel中创建了一个Garbage模型,迁移文件代码如下:

Schema::create('garbages', function (Blueprint $table) {
    $table->id();
    $table->date('disposal_at');
    $table->timestamps();
});

在web.php路由中,我获取所有记录并按disposal_at排序后传递给Inertia:

Route::get('/garbage', function() {
    $garbages = \App\Models\Garbage::all()
        ->sortBy('disposal_at');

    // dd($garbage); 确认Laravel中集合已按disposal_at排序

    return Inertia::render('Grabage', [
        'garbages' => $garbages
    ]);
});

Vue组件代码如下:

<script setup lang="ts">
    interface Garbage {
        id: number,
        disposal_at: string
    }

    const props = defineProps<{
        garbages: Garbage[]
    }>();
</script>

<template>
    <ul>
        <li v-for="garbage in garbages" :key="garbage.id">
            {{ garbage.disposal_at }}
        </li>
    </ul>
</template>

但实际输出的列表并没有按disposal_at排序,而是回到了按id排序的状态,虽然在Laravel端用dd()确认集合是排序好的。

原因

Laravel的sortBy()方法返回的是保留原主键作为键名的关联集合,当Inertia将这个集合序列化为JSON传递给Vue时,会保留这些键名。而JavaScript在处理带有数字键的对象时,会自动按数字键的升序重新排列,导致Vue渲染时顺序变回原id的顺序。

解决方法

方案1:重置集合键名

在Laravel端使用values()方法重置集合的键,将其转换为连续索引的普通数组,这样序列化后Vue就能保持原排序:

Route::get('/garbage', function() {
    $garbages = \App\Models\Garbage::all()
        ->sortBy('disposal_at')
        ->values(); // 重置键名

    return Inertia::render('Grabage', [
        'garbages' => $garbages
    ]);
});

方案2:数据库层面排序(推荐)

直接在查询时使用orderBy()让数据库返回排序好的结果,这种方式性能更优,还能避免集合排序带来的键名问题:

Route::get('/garbage', function() {
    $garbages = \App\Models\Garbage::orderBy('disposal_at')->get();

    return Inertia::render('Grabage', [
        'garbages' => $garbages
    ]);
});

内容的提问来源于stack exchange,提问作者Stephan Busse

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 09:40:18