vue 表格 vxetable 如何获取已修改的单元格数据

在数据管理系统中,用户对表格进行编辑后,我们往往需要快速定位哪些行或单元格被修改,以便提交到后端进行增量更新。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。
  • 扩展操作:提供撤销、清除、状态判断等实用方法。

https://vxetable.cn