OctoberCMS自定义分页实现:页码列表或动态加载方案求助
自定义分页实现方案(页码列表 + 动态加载)
嘿,针对你这段Laravel查询代码的分页需求,我给你整理了两种自定义分页的实现方式,直接上手就能用:
一、自定义页码列表显示
你的后端查询代码其实不用大改,paginate(15)已经帮你生成了包含分页元数据的LengthAwarePaginator实例,核心是在前端视图里自定义渲染逻辑:
1. 发布Laravel默认分页视图(可选但推荐)
如果你想完全自定义页码的HTML结构,可以先把Laravel的分页视图文件发布到本地:
php artisan vendor:publish --tag=laravel-pagination
执行后,你会在resources/views/vendor/pagination/目录下看到分页模板文件,比如default.blade.php,直接修改这个文件就能全局替换分页样式。
2. 手动渲染自定义页码(适合单页面定制)
如果只是某个页面需要自定义,不用发布全局模板,直接在视图里写逻辑就行。假设你把查询结果赋值给了$paintings变量:
<div class="pagination"> <!-- 上一页按钮 --> @if($paintings->onFirstPage()) <span class="page-link disabled">上一页</span> @else <a href="{{ $paintings->previousPageUrl() }}" class="page-link">上一页</a> @endif <!-- 页码列表 --> @foreach($paintings->getUrlRange(1, $paintings->lastPage()) as $page => $url) @if($page == $paintings->currentPage()) <span class="page-link active">{{ $page }}</span> @else <a href="{{ $url }}" class="page-link">{{ $page }}</a> @endif @endforeach <!-- 下一页按钮 --> @if($paintings->hasMorePages()) <a href="{{ $paintings->nextPageUrl() }}" class="page-link">下一页</a> @else <span class="page-link disabled">下一页</span> @endif </div>
这样就能生成带高亮当前页、上/下一页禁用状态的自定义页码列表,样式可以自己加CSS调整。
二、动态加载(无限滚动/点击加载更多)
如果不想显示页码,想用动态加载的方式,需要前后端配合调整:
1. 后端调整:支持AJAX请求
在控制器里判断请求类型,如果是AJAX请求,返回JSON格式的数据,否则返回视图:
public function index() { $paintings = Painting::where('type', input("type")) ->where('material', input("material")) ->whereHas('artist', function($q) { $q->where('artist_slug', '=', $this->param('slug')); }) ->paginate(15); if(request()->ajax()) { return response()->json([ 'data' => view('partials.painting-item', ['paintings' => $paintings])->render(), 'next_page_url' => $paintings->nextPageUrl() ]); } return view('paintings.index', compact('paintings')); }
这里假设你把单条绘画的HTML放在partials.painting-item视图里,这样AJAX返回的是渲染好的HTML片段,直接追加到页面就行。
2. 前端实现:点击加载/无限滚动
方式一:点击加载更多
在页面里加一个“加载更多”按钮,用JS监听点击事件:
<div id="paintings-list"> @foreach($paintings as $painting) @include('partials.painting-item', ['painting' => $painting]) @endforeach </div> <button id="load-more" data-next-url="{{ $paintings->nextPageUrl() }}">加载更多</button> <script> const loadMoreBtn = document.getElementById('load-more'); const paintingsList = document.getElementById('paintings-list'); loadMoreBtn.addEventListener('click', async () => { const nextUrl = loadMoreBtn.dataset.nextUrl; if(!nextUrl) { loadMoreBtn.textContent = '没有更多内容了'; loadMoreBtn.disabled = true; return; } try { const response = await fetch(nextUrl); const data = await response.json(); paintingsList.insertAdjacentHTML('beforeend', data.data); loadMoreBtn.dataset.nextUrl = data.next_page_url; if(!data.next_page_url) { loadMoreBtn.textContent = '没有更多内容了'; loadMoreBtn.disabled = true; } } catch(error) { console.error('加载失败:', error); } }); </script>
方式二:无限滚动(滚动到底部自动加载)
把点击事件换成滚动监听:
<div id="paintings-list"> @foreach($paintings as $painting) @include('partials.painting-item', ['painting' => $painting]) @endforeach </div> <div id="loading" style="display:none;">加载中...</div> <script> const paintingsList = document.getElementById('paintings-list'); const loading = document.getElementById('loading'); let nextUrl = "{{ $paintings->nextPageUrl() }}"; let isLoading = false; window.addEventListener('scroll', async () => { if(isLoading || !nextUrl) return; // 判断是否滚动到页面底部附近 if(window.innerHeight + window.scrollY >= document.body.offsetHeight - 100) { isLoading = true; loading.style.display = 'block'; try { const response = await fetch(nextUrl); const data = await response.json(); paintingsList.insertAdjacentHTML('beforeend', data.data); nextUrl = data.next_page_url; if(!nextUrl) { loading.textContent = '没有更多内容了'; } } catch(error) { console.error('加载失败:', error); loading.textContent = '加载失败,点击重试'; } finally { isLoading = false; loading.style.display = 'none'; } } }); </script>
这样两种动态加载的方式都能实现,根据你的需求选就行~
内容的提问来源于stack exchange,提问作者viabcua




