我们需要渲染一个4行3列的表格,我们只需要配置好columns:[{},{},{}],数据dataSource:[{},{},{},{}],当我们columns中对象的属性与dataSource中对象的属性对应时,就可以正常渲染数据啦。但是当我们的后端不是以每行数据进行返回,而是将每个单元格的数据作为一个对象返回时,我们就要自己按行处理数据了。接下来分享一下我的思路。
解题思路: 1、不管后端返回给我们多少条数据,我们只需要明确我们需要的是几行数据,也就是需要定义包含几个对象的数组。 2、根据后端返回每个单元格中的两个字段唯一确定行和列。再根据行列取出对应单元格数据添加到刚才创建的数组中,就可以成功渲染数据了。
具体实现:
- 定义tableColumns:我这里的列和行相等,是动态的数据根据num进行遍历渲染得到
js
computed: {
tableColumns() {
this.list = []
let columnsTemp = public_deepCopy(this.columns);
for (let i = 0; i < this.num; i++) {
this.list.push({
title: i + 1,
dataIndex: i + 1,
key: i + 1,
align: 'center',
scopedSlots: {customRender: i + 1}
});
}
columnsTemp.push(...this.list)
return columnsTemp
}
}
- 定义一个函数,用来初始化行,方便处理后端返回的数据
- 先来看一下后端返回数据格式
我这里的num和sort就可以唯一确定是哪个单元格,num代表行号,sort代表列号
- 接下来我们开始定义函数初始化行数据
js
getArray(arr) {
// 初始化行,这里根据num的值确定需要几行,创建包含几个对象的空数据
const rows = Array.from({length: this.num}, () => ({}));
// 根据num也就是行数-1,确定索引,我们可以知道像一行添加数据,在将sort作为对象的属性名,item作为属性值将数据存储到对应的位置
arr.forEach(item => {
rows[item.num - 1][item.sort] = {
...item,
score: item.numerator && item.denominator ? item.numerator + '/' + item.denominator : ''
};
});
// 因为有的单元格没有数据,所以进行判断将空位置填充为null
rows.forEach(row => {
for (let i = 1; i <= this.num; i++) {
if (!row.hasOwnProperty(i)) {
row[i] = null;
}
}
});
//最后将处理好的数据返回
return rows;
},
- 调接口处理数据
js
async queryTemplate() {
this.loading = true
const res = await queryWorkAllocationModule({
moduleId: this.moduleId
});
this.loading = false;
if (res.state === 200) {
this.dataSource = this.getArray(res.data);
} else {
this.$message.error(res.message)
}
},
- 处理好的数据结构就是这样啦,这样就可以跟我们上面定义的tableColumns数组包含的对象属性进行一一对应了
- 渲染数据
js
<a-table
:columns="tableColumns"
:data-source="dataSource"
:loading="loading"
:pagination="false"
:rowKey="record => record.id"
bordered
>
<template slot="headerName">
<div style="position:relative;width:100px;">
<div style="text-align: right;">排名</div>
<div style="text-align: left;">人数</div>
</div>
</template>
<template slot="header" slot-scope="text, record, index">
{{ index + 1 }}
</template>
<template v-for="item in num" :slot="item" slot-scope="text, record, index">
<a-input v-if="record[item] && commenttype" :key="index"
v-model="text.score" placeholder="请输入" style="text-align: center;border: none"></a-input>
<span v-if="record[item] && !commenttype">{{ text.score }}</span>
</template>
</a-table>
- 最后放上最终效果图展示
数据处理完成,表格可以正确的被渲染出来了。