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

如何在Nuxt前端实现Laravel Lighthouse分页功能

传统偏移分页实现方案

1. 调整GraphQL查询结构

首先确保查询中明确返回分页所需的元数据字段:

query GetBlogs($first: Int!, $page: Int!) {
  blogs(first: $first, page: $page) {
    paginatorInfo {
      currentPage
      lastPage
      perPage
      total
      hasMorePages
    }
    data {
      id
      title
      content
      created_at
      # 其他需要返回的博客字段
    }
  }
}

2. 页面层查询逻辑实现

在Nuxt页面中使用Apollo的查询能力,绑定响应式的页码变量,页码变化时自动重新发起请求:

<template>
  <div>
    <!-- 博客列表渲染 -->
    <div v-for="blog in blogs.data" :key="blog.id" class="blog-item">
      <h2>{{ blog.title }}</h2>
      <p>{{ blog.content }}</p>
    </div>
    <!-- 引入分页组件 -->
    <Pagination 
      :current-page="blogs.paginatorInfo.currentPage"
      :last-page="blogs.paginatorInfo.lastPage"
      @change-page="handlePageChange"
    />
  </div>
</template>

<script setup>
import { useQuery } from '@vue/apollo-composable'
import gql from 'graphql-tag'

// 配置每页展示条数
const PER_PAGE = 5
// 响应式当前页码,默认第一页
const currentPage = ref(1)

// 绑定查询参数,currentPage变化时自动触发重新查询
const { result } = useQuery(gql`
query GetBlogs($first: Int!, $page: Int!) {
  blogs(first: $first, page: $page) {
    paginatorInfo {
      currentPage
      lastPage
      perPage
      total
      hasMorePages
    }
    data {
      id
      title
      content
      created_at
    }
  }
}
`, () => ({
  first: PER_PAGE,
  page: currentPage.value
}))

// 格式化返回的博客数据
const blogs = computed(() => result.value?.blogs || { paginatorInfo: {}, data: [] })

// 处理页码切换事件
const handlePageChange = (page) => {
  currentPage.value = page
  // 可选配置:切换页码后滚动到页面顶部
  window.scrollTo({ top: 0, behavior: 'smooth' })
}
</script>

3. 分页组件逻辑完善

对已有的基础分页组件补充props和事件绑定逻辑:

<template>
  <div class='btn-group bg-white py-2 items-center justify-center'>
    <button 
      class='btn' 
      :disabled="currentPage === 1"
      @click="$emit('change-page', currentPage - 1)"
    >
      上一页
    </button>
    <button 
      v-for="page in lastPage" 
      :key="page"
      class='btn'
      :class="{ 'btn-active': page === currentPage }"
      @click="$emit('change-page', page)"
    >
      {{ page }}
    </button>
    <button 
      class='btn' 
      :disabled="currentPage === lastPage"
      @click="$emit('change-page', currentPage + 1)"
    >
      下一页
    </button>
  </div>
</template>

<script setup>
const props = defineProps({
  currentPage: {
    type: Number,
    required: true
  },
  lastPage: {
    type: Number,
    required: true
  }
})

defineEmits(['change-page'])
</script>

<style scoped>
.btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
</style>

可选优化

如果总页数过多,可调整分页组件的页码渲染逻辑,仅展示当前页前后2-3个页码,多余部分用省略号替代,避免分页栏过长。


内容的提问来源于stack exchange,提问作者niels van hoof

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 19:06:02