Vue3使用Quasar Table展示更新API返回对象数组异常如何解决
问题根因
- 数组未清空:
interactors、rows两个数组声明在setup作用域下,每次触发搜索都没有清空旧数据,直接push就会不断累加重复条目。 - loading逻辑写反:模板里表格用
v-if="loading"控制显示,你异步请求数据过程中没有修改loading状态,之前注释掉的loading.value = false一执行,表格就会被销毁,所以会出现数据刚填充完就消失的情况。 - 异步逻辑顺序错误:
fetchData是异步函数,你调用后没有等待它执行完成,后续对rows的操作时机不对,而且你把临时存储的ids_interactor、interactors放在全局作用域,容易出现数据污染。 - q-table的row-key配置错误:你配置的是
row-key="name",但你的rows对象里根本没有name字段,只有interactor_id和official_symbol,这会导致Quasar表格渲染时key冲突,出现渲染异常。
修正方案
1. 模板修正
调整loading逻辑:加载中显示加载状态,加载完成显示表格,同时修正row-key配置:
<template> <q-select rounded outlined bottom-slots v-model="version" :options="options" label="Select Database Version" :dense="false" :options-dense="false" > </q-select> <div class ="searchButton"> <div class="q-pa-md"> <div class="q-gutter-md" style="max-width: 300px"> <q-input v-model="gene" label="Find your gene !" /> <q-btn @click="search" label="Search" :loading="loading" /> <q-icon name="search" /> </div> </div> </div> <br/> <br/> <!-- 加载完成后显示表格 --> <div v-if="!loading" class="q-pa-md" id = 'table'> <q-table title="Ligand - Receptor" :rows="rows" :columns="columns" row-key="interactor_id" /> </div> <q-inner-loading :show="loading" label="数据加载中"/> </template>
2. Script逻辑修正
- 每次搜索前清空所有旧数据
- 调整loading状态的时机:搜索开始时设为true,请求完成后设为false
- 把临时变量
ids_interactor、interactors放到fetchData内部,避免全局污染
<script lang="ts"> import { defineComponent, ref, onMounted } from 'vue'; import { ReleasesApi } from '../api/ReleasesApi'; import Interactor from '@/models/Interactor'; export default defineComponent ({ setup () { const gene = ref<string>("TIE1") const version = ref<string>("1"); const options = ref<string[]>(["1","2"]); const loading = ref<boolean>(false); const error = ref<boolean>(false); const rows = ref<{interactor_id:number, official_symbol:string}[]>([]); const columns = [ { name: 'interactor_id',required: true,label: 'interactor_id',align: 'left',field: row => row.interactor_id,format: val => `${val}`,sortable: true }, { name: 'official_symbol',required: true,label: 'official_symbol',align: 'left',field: row => row.official_symbol,format: val => `${val}`,sortable: true } ]; onMounted (() => {console.log("Mounted") }); async function search () { // 搜索开始,清空旧数据,开启加载状态 loading.value = true error.value = false rows.value = [] try { const ids_interactor = await ReleasesApi.getIndexInteractions(version.value,gene.value); const interactors: Interactor[] = [] for (const type of ["ligand","receptor"] ) { for (const id of ids_interactor) { const interactor : Interactor = await ReleasesApi.getInteractorsUsingTypeAndIndex(type,id); interactors.push(interactor[0]); } } // 组装rows数据 const ligandList = interactors.filter(interactor=>interactor.type=="ligand") rows.value = ligandList.map(item => ({ interactor_id: item.interactor_id, official_symbol: item.official_symbol })) } catch (e) { if (e instanceof TypeError) { error.value = true } } finally { // 无论请求成功失败,统一关闭加载状态 loading.value = false } } return { loading,error,version,gene,options,columns,rows,search} } }); </script>
额外说明
- 不需要用splice清空数组,直接给
rows.value赋值空数组即可触发响应式更新 - 临时变量放到函数内部,每次请求都会重新初始化,不会出现数据串扰的问题
- row-key用唯一的interactor_id,避免Quasar表格渲染异常
内容的提问来源于stack exchange,提问作者ZheFrench
相关产品推荐
相关产品推荐

