如何使用Vuetify或Bootstrap-Vue实现带URL参数的新闻列表分页功能
Vue分页功能实现方案(适配Vuetify/Bootstrap-Vue + Vuex + 路由同步)
核心实现逻辑
- 路由参数绑定:将
page(当前页码)、pageSize(每页条数)作为路由query参数存储,页面初始化直接读取参数作为分页初始值,参数变更时自动驱动数据更新,刷新页面仍可保留当前分页状态 - Vuex数据处理:全量新闻数据存储在Vuex state中,通过带参数的getters实现数据切片,直接返回当前页对应的数据,无需在组件内处理全量数据
- 分页更新规则:用户切换页码时优先修改路由query参数,不直接修改组件内的页码变量,通过路由参数响应式变更自动触发分页数据更新,保证状态和URL完全同步
- 渲染逻辑:组件仅绑定分页getters返回的当前页数据渲染卡片,避免全量渲染导致页面过长
可运行代码示例
1. Vuex配置(store/index.js)
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) export default new Vuex.Store({ state: { // 模拟全量新闻数据,实际场景可在接口请求后存入state newsList: Array.from({length: 120}, (_, index) => ({ id: index + 1, title: `新闻标题${index + 1}`, content: `这是第${index + 1}条新闻的摘要内容,支持自定义扩展字段`, publishTime: `2024-0${Math.floor(index / 20) + 1}-${(index % 20) + 1}` })) }, getters: { // 分页查询新闻,接收当前页、每页条数作为入参 getPagedNews: (state) => (currentPage, pageSize) => { const startIndex = (currentPage - 1) * pageSize const endIndex = startIndex + pageSize return state.newsList.slice(startIndex, endIndex) }, // 获取新闻总条数,用于计算总页数 getNewsTotalCount: (state) => state.newsList.length } })
2. 路由配置(router/index.js)
import Vue from 'vue' import VueRouter from 'vue-router' import NewsList from '../views/NewsList.vue' Vue.use(VueRouter) const routes = [ { path: '/news', name: 'NewsList', component: NewsList }, // 其他路由配置... ] const router = new VueRouter({ mode: 'history', // hash模式也可正常使用,无需修改逻辑 routes }) export default router
3. 新闻列表页组件(views/NewsList.vue,基于Vuetify实现)
<template> <v-container class="my-5"> <!-- 新闻卡片列表 --> <v-row> <v-col cols="12" md="6" lg="4" v-for="item in currentPageNews" :key="item.id"> <v-card class="mb-4" height="200"> <v-card-title class="text-h6">{{ item.title }}</v-card-title> <v-card-subtitle>{{ item.publishTime }}</v-card-subtitle> <v-card-text>{{ item.content }}</v-card-text> </v-card> </v-col> </v-row> <!-- 分页组件 --> <v-pagination v-model="currentPage" :length="totalPage" :total-visible="7" class="d-flex justify-center mt-4" ></v-pagination> </v-container> </template> <script> export default { name: 'NewsList', data() { return { // 每页展示条数,可根据业务需求调整 pageSize: 12 } }, computed: { // 页码绑定路由query参数 currentPage: { get() { return Number(this.$route.query.page) || 1 }, set(newPage) { // 页码变化时更新路由参数 this.$router.push({ query: { ...this.$route.query, page: newPage } }) } }, // 从Vuex获取当前页的新闻数据 currentPageNews() { return this.$store.getters.getPagedNews(this.currentPage, this.pageSize) }, // 计算总页数 totalPage() { return Math.ceil(this.$store.getters.getNewsTotalCount / this.pageSize) } }, watch: { // 监听路由参数变化,触发数据自动更新 '$route.query.page': { immediate: true, handler() {} } } } </script>
4. 基于Bootstrap-Vue的分页组件替换方案
如果使用Bootstrap-Vue,只需要把模板中的分页组件替换为如下代码即可,其余逻辑完全一致:
<b-pagination v-model="currentPage" :total-rows="totalPage * pageSize" :per-page="pageSize" align="center" class="mt-4" ></b-pagination>
扩展说明
如果新闻数据需要异步从后端接口获取,只需要在路由参数的watch回调中增加接口请求逻辑,拿到对应页的数据后存入Vuex即可,无需修改其他分页逻辑。如果需要支持用户自定义每页条数,参照currentPage的绑定逻辑,将pageSize也绑定到路由query参数即可。
内容的提问来源于stack exchange,提问作者1 2
相关产品推荐
相关产品推荐

