在数据管理系统中,用户对表格进行编辑后,我们往往需要快速定位哪些行或单元格被修改,以便提交到后端进行增量更新。vxe-table 内置了 CRUD 管理器,可以自动追踪数据变更行为。只需开启 keepSource 配置,即可通过 getUpdateRecords 和 getUpdateCells 方法,轻松获取所有修改过的行数据或单元格信息。
说明
vxe-table 的 CRUD 管理器会在数据编辑、单元格变更时自动记录操作痕迹。为了启用这一能力,你需要:
- 开启 keepSource: true(保持数据源副本,用于对比变更)。
- 设置 rowConfig.keyField(行唯一标识,用于精确匹配行)。
- 开启编辑配置(可选,但不开启编辑也可以手动修改数据触发记录)。
原理:开启 keepSource 后,表格内部会保存一份原始数据的深拷贝。当数据发生变化时,通过对比原始数据与当前数据,自动生成变更记录。
相关 API
| 方法 | 返回类型 | 说明 |
|---|---|---|
| getUpdateRecords() | Array | 获取所有被修改过的行数据(完整行对象),每个对象包含行数据和修改状态。 |
| getUpdateCells() | Array | 获取所有被修改过的单元格详情,包含行信息、字段名、旧值、新值等。 |
| getRecordStatus(row) | String | 获取指定行的状态:'insert'、'update'、'remove' 或 null(未变更)。 |
| getUpdateRecord(row) | Object | 获取指定行的变更记录(包括修改的字段和新旧值)。 |
| revertUpdateRecord(row) | void | 撤销对指定行的所有修改,恢复为原始数据。 |
| clearUpdateRecord(row) | void | 清除指定行的变更记录(但不撤销数据修改)。 |
代码

html
<template>
<div>
<vxe-button status="success" @click="getUpdateEvent">获取已修改的行</vxe-button>
<vxe-button status="success" @click="getUpdateCellEvent">获取已修改的单元格</vxe-button>
<vxe-grid ref="gridRef" v-bind="gridOptions">
<!-- 操作列:模拟外部修改数据 -->
<template #action="{ row }">
<vxe-button mode="text" status="primary" @click="updateRowName(row)">修改名称</vxe-button>
<vxe-button mode="text" status="primary" @click="updateRowAge(row)">年龄+1</vxe-button>
</template>
</vxe-grid>
</div>
</template>
<script setup>
import { ref, reactive } from 'vue'
import { VxeUI } from 'vxe-table'
const gridRef = ref()
const gridOptions = reactive({
border: true,
height: 400,
showOverflow: true,
// 1. 必须开启 keepSource,才能追踪变更
keepSource: true,
// 2. 必须设置 keyField,用于匹配行
rowConfig: {
keyField: 'id'
},
// 3. 启用单元格编辑(可选,也可以直接修改数据)
editConfig: {
trigger: 'click',
mode: 'cell',
showStatus: true // 显示修改标记(小圆点)
},
columns: [
{ type: 'seq', width: 70 },
{ field: 'name', title: '姓名', editRender: { name: 'input' } },
{ field: 'sex', title: '性别', editRender: { name: 'input' } },
{ field: 'age', title: '年龄', editRender: { name: 'input' } },
{
field: 'action',
title: '操作',
width: 200,
slots: { default: 'action' }
}
],
data: []
})
// 模拟加载数据
const loadData = () => {
gridOptions.loading = true
setTimeout(() => {
gridOptions.data = [
{ id: 10001, name: 'Test1', role: 'Develop', sex: 'Man', age: 28, address: 'test abc' },
{ id: 10002, name: 'Test2', role: 'Test', sex: 'Women', age: 22, address: 'Guangzhou' },
{ id: 10003, name: 'Test3', role: 'PM', sex: 'Man', age: 32, address: 'Shanghai' },
{ id: 10004, name: 'Test4', role: 'Designer', sex: 'Women', age: 24, address: 'Shanghai' }
]
gridOptions.loading = false
}, 200)
}
// 外部修改数据:修改名称
const updateRowName = (row) => {
row.name = `Name_${new Date().getTime()}`
}
// 外部修改数据:年龄加1
const updateRowAge = (row) => {
row.age++
}
// 获取所有已修改的行
const getUpdateEvent = () => {
const $grid = gridRef.value
if ($grid) {
const updateRecords = $grid.getUpdateRecords()
VxeUI.modal.alert(`共修改了 ${updateRecords.length} 行`)
console.log('已修改的行:', updateRecords)
}
}
// 获取所有已修改的单元格
const getUpdateCellEvent = () => {
const $grid = gridRef.value
if ($grid) {
const updateCells = $grid.getUpdateCells()
VxeUI.modal.alert(`共修改了 ${updateCells.length} 个单元格`)
console.log('已修改的单元格详情:', updateCells)
}
}
loadData()
</script>
getUpdateRecords 与 getUpdateCells 的区别
| 方法 | 返回数据 | 适用场景 |
|---|---|---|
| getUpdateRecords() | 被修改过的行对象数组(每行包含所有字段,状态标记为 update )。 | 需要提交整行数据(如全字段更新),适合简单的后端接口。 |
| getUpdateCells() | 详细的单元格变更列表,包含 row(行数据)、field(字段名)、oldValue(旧值)、newValue(新值)、status(状态)。 | 需要精细控制每个字段变更,适合增量更新或审计日志。 |
vxe-table 的 CRUD 管理器通过 keepSource + keyField 两个配置,即可自动追踪所有数据变更。开发者无需手动记录修改,只需调用 getUpdateRecords 或 getUpdateCells 就能获取精确的修改信息,极大简化了"保存修改"这一常见业务逻辑的实现。
- 轻量级场景(只关心哪些行变了):使用 getUpdateRecords。
- 精细控制场景(需要记录每个字段变更):使用 getUpdateCells。
- 扩展操作:提供撤销、清除、状态判断等实用方法。