Vue.js实现表格过滤排序时输入搜索内容表格为空问题排查
问题根因
你输入过滤内容后表格清空是4个代码错误导致的:
- 字段名大小写不匹配:过滤逻辑里写的是
el.UtenteTessera、el.UtenteNome这种大驼峰属性,但你模板渲染用的是utente.tessera、utente.nome全小写字段,过滤时访问不存在的属性会直接触发JS错误,最终filter返回空数组 - 原始数据源被污染:拉接口时你把同一个数组对象同时赋值给
utenti和utentiWithoutFilter,后续调用sort排序会直接修改原数组,导致过滤依赖的全量数据源被改坏 - 列表key绑定错误:v-for循环里
:key="title"绑定了根本不存在的title字段,Vue更新列表时会出现渲染异常 - 漏了数据拉取触发时机:代码里没看到组件挂载时调用
refreshData的逻辑,不手动触发的话初始都拿不到数据
修复方案
脚本部分修改
<script> import axios from 'axios' export default { name: 'Utenti', data() { return { utenti: [], modalTitle: '', UtenteTessera: 0, UtenteNome: '', UtenteCognome: '', UtenteEmail: '', UtenteTelefono: '', UtenteNomeFilter: '', UtenteTesseraFilter: '', utentiWithoutFilter: [], } }, mounted() { // 组件挂载时自动拉取数据 this.refreshData() }, methods: { refreshData() { axios.post('https://localhost:7285/Utenti/GetDati').then((response) => { // 深拷贝两份独立数据,避免后续排序、过滤操作污染原始全量数据 const rawData = JSON.parse(JSON.stringify(response.data.prova)) this.utenti = rawData this.utentiWithoutFilter = JSON.parse(JSON.stringify(response.data.prova)) }) }, FilterFn() { const tesseraFilter = this.UtenteTesseraFilter.toString().trim().toLowerCase() const nomeFilter = this.UtenteNomeFilter.toString().trim().toLowerCase() this.utenti = this.utentiWithoutFilter.filter(function (el) { // 字段名和接口返回的小写字段对齐,加空值兜底避免访问属性报错 const matchTessera = (el.tessera?.toString().toLowerCase() || '').includes(tesseraFilter) const matchNome = (el.nome?.toString().toLowerCase() || '').includes(nomeFilter) return matchTessera && matchNome }) }, sortResult(prop, asc) { // 基于当前过滤后的结果排序,浅拷贝后再排序避免修改原始数组 this.utenti = [...this.utenti].sort(function (a, b) { const valA = a[prop] const valB = b[prop] if (asc) { return valA > valB ? 1 : valA < valB ? -1 : 0 } else { return valB > valA ? 1 : valB < valA ? -1 : 0 } }) }, }, } </script>
模板部分修改
- 修正v-for的key绑定,用数据里唯一的tessera字段作为key:
<tr v-for="utente in utenti" :key="utente.tessera"> <td>{{ utente.tessera }}</td> <td>{{ utente.nome }}</td> <td>{{ utente.cognome }}</td> <td>{{ utente.email }}</td> <td>{{ utente.telefono }}</td> </tr>
- 修正排序按钮的传参,把原来的大驼峰字段名改成和接口一致的小写字段:
<!-- 卡号列排序按钮,把传参从'UtenteTessera'改成'tessera' --> <button type="button" class="btn btn-light" @click="sortResult('tessera', true)"> <button type="button" class="btn btn-light" @click="sortResult('tessera', false)"> <!-- 名列排序按钮,把传参从'UtenteNome'改成'nome' --> <button type="button" class="btn btn-light" @click="sortResult('nome', true)"> <button type="button" class="btn btn-light" @click="sortResult('nome', false)">
可选优化
后续可以把过滤排序逻辑改成计算属性实现,不用手动维护utenti和utentiWithoutFilter两个数组,代码会更简洁好维护;接口请求建议加catch错误捕获,避免接口报错时页面无响应。
内容的提问来源于stack exchange,提问作者Mars95
相关产品推荐
相关产品推荐

