vue实现分页搜索功能
Vue 分页搜索功能实现
分页搜索功能通常需要结合后端API,前端实现主要包括数据请求、分页逻辑和搜索条件绑定。以下是基于Vue 3和Element Plus的完整实现方案。
基础模板结构
使用Element Plus的el-pagination组件和el-input组件构建界面:
<template>
<div>
<el-input v-model="searchQuery" placeholder="输入关键词搜索" @keyup.enter="handleSearch" />
<el-table :data="tableData">
<!-- 表格列定义 -->
</el-table>
<el-pagination
v-model:current-page="currentPage"
:page-size="pageSize"
:total="total"
@current-change="handlePageChange"
/>
</div>
</template>
核心状态管理
在script部分定义响应式数据和初始化方法:
import { ref, onMounted } from 'vue'
import axios from 'axios'
const tableData = ref([])
const searchQuery = ref('')
const currentPage = ref(1)
const pageSize = ref(10)
const total = ref(0)
const fetchData = async () => {
try {
const res = await axios.get('/api/data', {
params: {
page: currentPage.value,
size: pageSize.value,
query: searchQuery.value
}
})
tableData.value = res.data.list
total.value = res.data.total
} catch (error) {
console.error('获取数据失败:', error)
}
}
事件处理函数
实现分页切换和搜索触发逻辑:

const handlePageChange = (newPage) => {
currentPage.value = newPage
fetchData()
}
const handleSearch = () => {
currentPage.value = 1 // 搜索时重置到第一页
fetchData()
}
onMounted(() => {
fetchData()
})
优化搜索体验
添加防抖处理避免频繁请求:
import { debounce } from 'lodash-es'
const debouncedSearch = debounce(handleSearch, 500)
// 修改input绑定
<el-input
v-model="searchQuery"
@input="debouncedSearch"
placeholder="输入关键词搜索"
/>
完整组件示例
组合所有功能后的完整组件:

<template>
<div class="pagination-demo">
<el-input
v-model="searchQuery"
placeholder="输入关键词搜索"
clearable
@clear="handleSearch"
@keyup.enter="handleSearch"
/>
<el-table :data="tableData" style="width: 100%">
<el-table-column prop="id" label="ID" width="180" />
<el-table-column prop="name" label="名称" width="180" />
<el-table-column prop="value" label="值" />
</el-table>
<el-pagination
v-model:current-page="currentPage"
:page-size="pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="total"
@size-change="handleSizeChange"
@current-change="handlePageChange"
/>
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue'
import { debounce } from 'lodash-es'
import axios from 'axios'
const tableData = ref([])
const searchQuery = ref('')
const currentPage = ref(1)
const pageSize = ref(10)
const total = ref(0)
const fetchData = async () => {
try {
const res = await axios.get('/api/data', {
params: {
page: currentPage.value,
size: pageSize.value,
query: searchQuery.value.trim()
}
})
tableData.value = res.data.list
total.value = res.data.total
} catch (error) {
console.error('获取数据失败:', error)
}
}
const handlePageChange = (newPage) => {
currentPage.value = newPage
fetchData()
}
const handleSizeChange = (newSize) => {
pageSize.value = newSize
currentPage.value = 1
fetchData()
}
const handleSearch = () => {
currentPage.value = 1
fetchData()
}
const debouncedSearch = debounce(handleSearch, 500)
onMounted(() => {
fetchData()
})
</script>
关键实现要点
- 分页参数管理:currentPage和pageSize需要作为请求参数发送到后端
- 搜索条件重置:执行搜索时需要将页码重置为1
- 防抖处理:对输入框的实时搜索进行性能优化
- 数据绑定:表格数据与分页器需要保持同步更新
后端API建议
后端接口应支持以下参数:
page: 当前页码size: 每页条数query: 搜索关键词
返回格式建议:
{
"list": [...],
"total": 100
}
样式优化建议
添加加载状态提升用户体验:
const loading = ref(false)
const fetchData = async () => {
loading.value = true
try {
// ...原有逻辑
} finally {
loading.value = false
}
}
// 在el-table添加loading属性
<el-table :data="tableData" v-loading="loading">






