Livewire 3分页异常:切换首页/第三、四页时功能失效
问题诊断与解决方案
核心问题分析
- 分页状态丢失:使用
getPostsProperty计算属性处理分页查询时,每次访问都会重新生成分页实例,Livewire的WithPaginationtrait无法正确维护page状态,导致页码参数失效,出现数据显示异常。 - 重复
wire:key引发渲染错误:两个模型的id可能重复,仅用$post->id作为wire:key会导致Livewire DOM对比逻辑混乱,引发数据渲染不全、分页按钮消失等问题。 - Union查询分页计数隐患:通过
DB::raw包装Union查询时,需确保绑定参数正确传递,避免总记录数计算错误。
修正后的代码
1. ProfileFeed.php 组件文件
移除计算属性,将查询逻辑移至render方法,显式传递分页页码参数:
<?php namespace App\Livewire; use App\Models\LawPost; use App\Models\QBankPost; use Livewire\Component; use Livewire\WithPagination; use Illuminate\Support\Facades\DB; class ProfileFeed extends Component { use WithPagination; protected $paginationTheme = 'tailwind'; public function render() { $qbankQuery = QBankPost::query() ->where('is_published', true) ->select('id', 'question as title', 'slug', 'answer as content', 'published_at', 'seo_image', 'label'); $lawPosts = LawPost::query() ->where('is_published', true) ->select('id', 'title', 'slug', 'content', 'published_at', 'seo_image', 'label'); $combinedQuery = $lawPosts->unionAll($qbankQuery); $posts = DB::table(DB::raw("({$combinedQuery->toSql()}) as combined")) ->mergeBindings($combinedQuery->getQuery()) ->orderBy('published_at', 'desc') ->paginate(10, ['*'], 'page', $this->page); return view('livewire.profile-feed', [ 'posts' => $posts, ]); } }
2. profile-feed.blade.php 视图文件
修改wire:key为唯一标识,避免重复冲突:
<div> @forelse ($posts as $post) <div wire:key="post-{{ $post->label }}-{{ $post->id }}"> <article class="group grid rounded-sm grid-cols-1 md:grid-cols-8 overflow-hidden border border-neutral-300 bg-neutral-50 text-neutral-600 dark:border-neutral-700 dark:bg-neutral-900 dark:text-neutral-300 mb-5"> <div class="flex items-center justify-center overflow-hidden mx-5 my-5"> <img src="{{ $post->seo_image ? asset($post->seo_image) : asset('images/' . $post->label . '/' . $post->slug . '.jpg') }}" class="h-52 md:h-full w-full object-cover transition duration-700 ease-out group-hover:scale-105" alt="{{ $post->title }}" /> </div> <div class="flex flex-col justify-center p-6 col-span-5"> <a href="{{ route("{$post->label}.show", $post->slug) }}"> <h3 class="text-balance text-xl font-bold text-neutral-900 lg:text-2xl dark:text-white">{{ $post->title }}</h3> <p class="my-4 max-w-lg text-pretty text-sm"> {!! Str::limit($post->content, 150) !!} </p> <span class="w-fit font-medium text-black underline-offset-2 hover:underline focus:underline focus:outline-hidden dark:text-white"> Published on: {{ \Carbon\Carbon::parse($post->published_at)->diffForHumans() }} </span> </a> </div> </article> </div> @empty No Post Found @endforelse <div class="mt-6"> {{ $posts->links() }} </div> </div>
额外处理方案(若总记录数仍异常)
如果Union查询的总记录数计算错误,可手动构造分页实例:
// 计算总记录数 $total = DB::table(DB::raw("({$combinedQuery->toSql()}) as combined")) ->mergeBindings($combinedQuery->getQuery()) ->count(); // 手动创建分页实例 $posts = new \Illuminate\Pagination\LengthAwarePaginator( DB::table(DB::raw("({$combinedQuery->toSql()}) as combined")) ->mergeBindings($combinedQuery->getQuery()) ->orderBy('published_at', 'desc') ->skip(($this->page - 1) * 10) ->take(10) ->get(), $total, 10, $this->page, ['path' => \Illuminate\Pagination\Paginator::resolveCurrentPath()] );
内容的提问来源于stack exchange,提问作者Siam Al Mahmud
相关产品推荐
相关产品推荐

