antd 表格动态行合并
合并效果
步骤方法
1.在computed节点下动态计算每次要合并的行数
computed: {
columns() {
return [
{
title: "区域",
dataIndex: "area",
customRender: (text, row, index) => {
const obj = {
children: text !== null ? text : "",
attrs: {
rowSpan: 1,
},
};
obj.attrs.rowSpan = this.renderCells(text, this.currentTable, "area",index);
return obj;
},
},
{
title: "名称",
dataIndex: "name",
},
{
title: "数量",
dataIndex: "count",
},
{
title: "进度",
dataIndex: "progress",
},
];
},
}
2.在methods节点下定义合并单元格的方法
renderCells(text, data, key, index) {
if (data.length < 1) {
return 1;
}
if (text === "" || text === null) {
data[index].rowNum = 1;
return 1;
}
// 上一行该列数据是否一样
if (index !== 0 && text === data[index - 1][key] && index % this.pagination.pageSize != 0) {
data[index].rowNum = 0;
return 0;
}
let rowSpan = 1;
// 判断下一行是否相等
for (let i = index + 1; i < data.length; i++) {
if (text !== data[i][key]) {
break;
}
rowSpan++;
}
data[index].rowNum = rowSpan;
return rowSpan;
}
3.如果是一次性获取所有数据进行分页的话,计算columns的时候需要进行修改一下
columns() {
return [
{
title: "区域",
dataIndex: "area",
customRender: (text, row, index) => {
const obj = {
children: text !== null ? text : "",
attrs: {
rowSpan: 1,
},
};
obj.attrs.rowSpan = this.renderCells(text, this.currentTable, "area", Number(index)+Number(this.pagination.pageSize * (this.pagination.current - 1)));
return obj;
},
},
{
title: "名称",
dataIndex: "name",
},
{
title: "数量",
dataIndex: "count",
},
{
title: "进度",
dataIndex: "progress",
},
];
},
参考文章:ant design vue 动态表格合并
合并效果
如果我们想要实现名称列相同的进行合并,需要在原来的代码上进行修改。合并的前提是区域相同,并且名称相同的情况下我们才进行合并,只需要在计算合并行数的时候需要加一层判断即可。
renderCells(text, data, key, index) {
if (data.length < 1) {
return 1;
}
if (text === "" || text === null) {
data[index].rowNum = 1;
return 1;
}
// 上一行该列数据是否一样
if (index !== 0 && text === data[index - 1][key] && index % this.pagination.pageSize != 0) {
if(key === 'name'){
if(data[index-1]['area'] === data[index]['area']){
data[index].rowNum = 0
return 0;
}
}else{
data[index].rowNum = 0;
return 0;
}
}
let rowSpan = 1;
// 判断下一行是否相等
for (let i = index + 1; i < data.length; i++) {
if(key === 'name' && data[i]['area'] !== data[index]['area']){
break;
}
if (text !== data[i][key] ) {
break;
}
rowSpan++;
}
data[index].rowNum = rowSpan;
return rowSpan;
},
单元格可编辑
非合并的行
可以参考官方的ant-design-vue可编辑单元格,官方示例如下:
<template>
<div>
<a-button class="editable-add-btn" @click="handleAdd">
Add
</a-button>
<a-table bordered :data-source="dataSource" :columns="columns">
<template slot="name" slot-scope="text, record">
<editable-cell :text="text" @change="onCellChange(record.key, 'name', $event)" />
</template>
<template slot="operation" slot-scope="text, record">
<a-popconfirm
v-if="dataSource.length"
title="Sure to delete?"
@confirm="() => onDelete(record.key)"
>
<a href="javascript:;">Delete</a>
</a-popconfirm>
</template>
</a-table>
</div>
</template>
<script>
const EditableCell = {
template: `
<div class="editable-cell">
<div v-if="editable" class="editable-cell-input-wrapper">
<a-input :value="value" @change="handleChange" @pressEnter="check" /><a-icon
type="check"
class="editable-cell-icon-check"
@click="check"
/>
</div>
<div v-else class="editable-cell-text-wrapper">
{{ value || ' ' }}
<a-icon type="edit" class="editable-cell-icon" @click="edit" />
</div>
</div>
`,
props: {
text: String,
},
data() {
return {
value: this.text,
editable: false,
};
},
methods: {
handleChange(e) {
const value = e.target.value;
this.value = value;
},
check() {
this.editable = false;
this.$emit('change', this.value);
},
edit() {
this.editable = true;
},
},
};
export default {
components: {
EditableCell,
},
data() {
return {
dataSource: [
{
key: '0',
name: 'Edward King 0',
age: '32',
address: 'London, Park Lane no. 0',
},
{
key: '1',
name: 'Edward King 1',
age: '32',
address: 'London, Park Lane no. 1',
},
],
count: 2,
columns: [
{
title: 'name',
dataIndex: 'name',
width: '30%',
scopedSlots: { customRender: 'name' },
},
{
title: 'age',
dataIndex: 'age',
},
{
title: 'address',
dataIndex: 'address',
},
{
title: 'operation',
dataIndex: 'operation',
scopedSlots: { customRender: 'operation' },
},
],
};
},
methods: {
onCellChange(key, dataIndex, value) {
const dataSource = [...this.dataSource];
const target = dataSource.find(item => item.key === key);
if (target) {
target[dataIndex] = value;
this.dataSource = dataSource;
}
},
onDelete(key) {
const dataSource = [...this.dataSource];
this.dataSource = dataSource.filter(item => item.key !== key);
},
handleAdd() {
const { count, dataSource } = this;
const newData = {
key: count,
name: `Edward King ${count}`,
age: 32,
address: `London, Park Lane no. ${count}`,
};
this.dataSource = [...dataSource, newData];
this.count = count + 1;
},
},
};
</script>
动态合并可编辑单元格
实际运用过程中,可能会遇到需要动态合并可编辑的单元格,已知scopedSlots可以帮助我们实现编辑单元格,customRender中可以自定义动态合并单元格。但是经过实践发现这两者无法同时使用。参考ant-design-vue表格动态合并可编辑单元格的解决方法发现可以通过JSX语法来解决scopedSlots和customRender冲突的问题文章来源:https://www.toymoban.com/news/detail-686109.html
computed: {
columns() {
return [
{
title: "区域",
dataIndex: "area",
scopedSlots: { customRender: 'area' },
customRender: (text, row, index) => {
const obj = {
children: <editable-cell text={text} onChange={(val) => this.onCellChange(row.id,'area',val)}></editable-cell>,
attrs: {
rowSpan: 1,
},
};
obj.attrs.rowSpan = this.mergeCells(text, this.currentTable, "area", Number(index)+Number(this.pagination.pageSize * (this.pagination.current - 1)));
return obj;
},
},
{
title: "名称",
dataIndex: "name",
},
{
title: "数量",
dataIndex: "count",
},
{
title: "进度",
dataIndex: "progress",
},
];
},
},
实现效果
文章来源地址https://www.toymoban.com/news/detail-686109.html
到了这里,关于ant vue table表格数据动态合并的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!