Vue.js中如何对数组属性的筛选子集进行分页?
实现Vue.js筛选后的数据分页(每页固定10条)
刚好之前做项目时也遇到过一模一样的需求——不管怎么筛选,每页就固定显示10条,完全理解你想要的效果!下面给你分享两种可行的实现思路,一种是自己手写核心逻辑(灵活可控),另一种是改造现有插件适配需求:
一、手写核心分页逻辑
这个思路的核心是先筛选,再分页,所有分页计算都基于筛选后的数据集,而不是Vuex里的原始数据。
1. 定义基础响应式数据
在组件里先声明需要的变量:
<script setup> import { ref, computed } from 'vue' import { useStore } from 'vuex' const store = useStore() // 筛选条件 const filters = ref({ size: '', type: '', name: '' }) // 当前页码 const currentPage = ref(1) // 每页固定条数 const pageSize = 10 </script>
2. 计算筛选后的数据集
用计算属性把Vuex里的原始数据和筛选条件结合,得到符合条件的结果:
<script setup> // ... 上面的代码 const filteredData = computed(() => { const originalData = store.state.yourDataKey // 替换成你Vuex里的数据集key if (!originalData) return [] // 处理数据未加载的情况 return originalData.filter(item => { // 这里根据你的筛选条件写判断逻辑,比如: const matchesSize = !filters.value.size || item.size === filters.value.size const matchesType = !filters.value.type || item.type === filters.value.type const matchesName = !filters.value.name || item.name.includes(filters.value.name) return matchesSize && matchesType && matchesName }) }) </script>
3. 计算当前页要显示的数据
再写一个计算属性,根据当前页码和每页10条,从筛选后的数据集里截取对应片段:
<script setup> // ... 上面的代码 const currentPageData = computed(() => { const startIndex = (currentPage.value - 1) * pageSize const endIndex = startIndex + pageSize return filteredData.value.slice(startIndex, endIndex) }) // 计算总页数,用于分页组件展示 const totalPages = computed(() => { return Math.ceil(filteredData.value.length / pageSize) }) </script>
4. 模板部分渲染数据和分页
在模板里直接用currentPageData渲染列表,分页部分根据totalPages和currentPage来做切换:
<template> <!-- 筛选控件 --> <div class="filters"> <input v-model="filters.size" placeholder="筛选尺寸" /> <select v-model="filters.type"> <option value="">所有类型</option> <option value="A">类型A</option> <option value="B">类型B</option> </select> <input v-model="filters.name" placeholder="搜索名称" /> </div> <!-- 列表渲染 --> <ul class="data-list"> <li v-for="item in currentPageData" :key="item.id">{{ item.name }} - {{ item.size }} - {{ item.type }}</li> </ul> <!-- 分页控件 --> <div class="pagination"> <button @click="currentPage = Math.max(1, currentPage - 1)" :disabled="currentPage === 1">上一页</button> <span>{{ currentPage }} / {{ totalPages }}</span> <button @click="currentPage = Math.min(totalPages, currentPage + 1)" :disabled="currentPage === totalPages">下一页</button> </div> </template>
二、改造现有分页插件适配需求
如果你已经在用某个分页插件,不用完全重写,只需要把插件需要的总条数换成filteredData.length,而不是原始数据的长度。
举个例子,假设插件需要传入total(总条数)、current-page(当前页)、page-size(每页条数)这几个props,那你只需要:
<template> <!-- 筛选控件和列表渲染和上面一样 --> <your-pagination-plugin :total="filteredData.length" :current-page="currentPage" :page-size="pageSize" @page-change="currentPage = $event" /> </template>
这样插件就会基于筛选后的结果来计算分页,自动实现每页10条的效果。
小提醒
- 记得给
v-for的列表项加上唯一的:key,避免Vue渲染出问题 - 筛选条件的判断逻辑可以根据你的实际业务调整,比如模糊匹配、区间筛选等
- 如果Vuex数据是异步加载的,计算属性里的空值判断能避免页面报错
内容的提问来源于stack exchange,提问作者dsp_099
相关产品推荐
相关产品推荐

