根据项目需求,实现表格数据不同显示红色背景,数据新增显示绿色背景 主要是采用唯一的id去比对,for循环缓存到map里面然后对比,不同的就存进去,不用每一个数组都push,在computed里面实现。
DiffTable.vue
<template>
<div class="diff-table-container">
<el-table v-for="(data, i) in completedData" :key="i" :data="data" :row-style="markRowStyles" :cell-style="markCellStyles" border>
<el-table-column v-for="item in columns" :key="`${i}${item.prop}`" v-bind="item" align="center" />
</el-table>
</div>
</template>
<script>
function deepClone (val) {
// 看需求要不要做深拷贝
return val;
}
export default {
name: "DiffTable",
props: {
uniqueKey: {
type: String,
default: "id"
},
dataGroup: {
type: Array,
validator: val => val.length === 2
},
columns: {
type: Array,
required: true
}
},
data () {
return {
DIFF_CELL_KEY: Symbol("diffCells"),
COMPLETED_KEY: Symbol("completed")
};
},
computed: {
// 处理完成的数据
completedData ({ dataGroup, uniqueKey, columns, DIFF_CELL_KEY, COMPLETED_KEY }) {
// 这一步不是必要的,根据业务需求来,如果规定不能修改原数据的话就做一下深拷贝
const _dataGroup = deepClone(dataGroup);
// Map<string|number, object>,ts不太熟,应该是这么写,其实就是row[unique]: row
const cacheMap = new Map();
// 先遍历一次第一组数据,初始化DIFF_CELL_KEY数组,然后存进map中
for (const _row of _dataGroup[0]) {
_row[DIFF_CELL_KEY] = [];
cacheMap.set(_row[uniqueKey], _row);
}
console.log(cacheMap, 'row')
// 遍历第二组数据,里面还有一次循环,因为只处理columns里面定义的属性,其他属性不做对比
for (const _row of _dataGroup[1]) {
for (const { prop } of columns) {
// 如果是唯一key就直接跳过
if (prop === uniqueKey) continue;
// 从缓存中查找相同的一条数据
const original = cacheMap.get(_row[uniqueKey]);
// 如果找不到就说明这条数据是新增的,直接跳过
if (!original) continue;
// 否则就在两组数据中打一个标识表示已处理过,不是新增的
_row[COMPLETED_KEY] = true;
original[COMPLETED_KEY] = true;
// 最后对比两个属性值,如果相同就push进DIFF_CELL_KEY数组中
// 注意这里DIFF_CELL_KEY数组只存在于第一组数据当中
// 因为只要有差异就会在所有表格中显示,所以不用每一组数据都存
_row[prop] !== original[prop] && original[DIFF_CELL_KEY].push(prop);
}
}
// 将map存一份到this中,因为会在处理样式的时候用到
this.$_cacheMap = cacheMap;
return _dataGroup;
}
},
methods: {
markRowStyles ({ row }) {
return (
!row[this.COMPLETED_KEY] && {
backgroundColor: "#E1F3D8"
}
);
},
markCellStyles ({ row, column }) {
const { $_cacheMap, uniqueKey, DIFF_CELL_KEY } = this;
const _cacheRow = $_cacheMap.get(row[uniqueKey]);
return (
_cacheRow &&
_cacheRow[DIFF_CELL_KEY].includes(column.property) && {
backgroundColor: "#FDE2E2"
}
);
}
}
};
</script>
<style scoped>
.diff-table-container {
display: flex;
align-items: flex-start;
}
.el-table + .el-table {
margin-left: 20px;
}
</style>
index.vue
<template>
<div class="Tabel_Data">
<diff-table :data-group="[oldData, newData]" :columns="tableColumns" />
</div>
</template>
<script>
import DiffTable from "./DiffTable";
export default {
name: "Index",
components: {
DiffTable
},
data () {
return {
oldData: [
{ id: 1, name: "zhangsan1", age: 23, address: "zxczxczxc", add: '0000' },
{ id: 2, name: "zhangsan2", age: 23.5, address: "zxczxczxc", add: '0000' },
{ id: 3, name: "zhangsan34", age: 23, address: "zxczxczxc", add: '0000' },
{ id: 4, name: "zhangsan4", age: 23, address: "zxczxczxc", add: '0000' },
{ id: 5, name: "zhangsan5", age: 23, address: "zxczxczxc", add: '0000' },
{ id: 6, name: "zhangsan5", age: 23, address: "zxczxczxc", add: '0000' }
],
newData: [
{ id: 1, name: "zhangsan1", age: 23, address: "zxczxczxc", add: '0000' },
{ id: 2, name: "zhangsan2", age: 23, address: "zxczxczxc", add: '0000' },
{ id: 4, name: "zhangsan4", age: 23, address: "地址地址地址", add: '00010' },
{ id: 3, name: "zhangsan3", age: 23, address: "zxczxczxc", add: '0000' },
{ id: 5, name: "zhangsan5", age: 23, address: "zxczxczxc", add: '0000' },
{ id: 7, name: "zhangsan5", age: 23, address: "zxczxczxc", add: '0000' },
{ id: 8, name: "zhangsan5", age: 23, address: "zxczxczxc", add: '0000' }
],
tableColumns: [
{ label: "id", prop: "id" },
{ label: "名称", prop: "name" },
{ label: "年龄", prop: "age" },
{ label: "地址", prop: "address" },
{ label: "地址1", prop: "add" },
]
};
}
};
</script>
最终的效果