You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

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

火山引擎 最新活动