点击addRow()后表格原有数据消失,items值始终为空的问题排查
问题
调用addRow()函数后,表格中已输入数据的原有行值会消失。该函数可成功为VDataTable添加新行,能在新行中输入数据,但输入后执行console.log(items.value)仍显示为空;再次点击addRow()时,仅会添加空对象,原有行的输入数据丢失。使用Vue3的<script setup>语法,相关代码如下:
HTML代码
<VDataTable :headers="headers" :items="items" :items-per-page="5" class="sale-table pa-4" > <template #item.product="{ item }"> <div class="d-flex gap-1"> <VAutocomplete v-model="item.product" label="Parts" density="compact" :items="parts" :custom-filter="customFilter" item-title="name" item-value="code" single-line /> </div> </template> <template #item.quantity="{ item }"> <div class="d-flex gap-1"> <VTextField v-model="item.quantity" label="Quantity" density="compact" single-line /> </div> </template> <template #item.price="{ item }"> <div class="d-flex gap-1"> <span class="price-display">৳{{ getPartPrice(item.product) }}</span> </div> </template> <template #item.discount="{ item }"> <div class="d-flex gap-1"> <VTextField v-model="item.discount" label="Discount (%)" density="compact" single-line /> </div> </template> <template #item.subtotal="{ item }"> <div class="d-flex gap-1"> <span class="subtotal-display">৳{{ calculateSubtotal(item) }}</span> </div> </template> </VDataTable>
JS代码
const customers = ref([]) const parts = ref([]) const items = ref([]) function addRow() { items.value.push({ product: null, quantity: null, discount: null, }) }
解决方案
问题核心是Vue3响应式系统无法追踪普通对象属性的变化,导致输入的数据无法同步到items的ref中,最终出现数据丢失的情况。
解决步骤
- 确保每一行的数据是响应式对象:使用
reactive()包装新增的行对象,让Vue能感知到对象属性的修改。 - 修改
addRow()函数,将普通对象替换为响应式对象。
修改后的JS代码:
import { ref, reactive } from 'vue' const customers = ref([]) const parts = ref([]) const items = ref([]) function addRow() { // 创建响应式行对象 const newRow = reactive({ product: null, quantity: null, discount: null, }) items.value.push(newRow) }
补充优化建议
- 确认
headers配置与行对象属性一一对应,避免组件渲染异常; - 给VDataTable添加
item-key属性(如:item-key="(item) => item._id"),帮助组件正确识别行数据; - 若涉及复杂计算,可使用
computed()包裹计算逻辑,确保数据更新时自动触发重渲染。
内容的提问来源于stack exchange,提问作者devquery
相关产品推荐
相关产品推荐

