antdテーブルの動的行マージ
マージエフェクト
ステップ法
1. 計算されたノードの下で毎回マージされる行の数を動的に計算します。
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. メソッドノードの下でセルを結合するメソッドを定義します。
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() {
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",
},
];
},
マージエフェクト
同じ名前の列とマージしたい場合は、元のコードを変更する必要があります。マージの前提は、領域が同じで、名前が同じであることです。マージされる行数を計算するときに判断レイヤーを追加するだけで済みます。
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 は動的に結合されたセルをカスタマイズできることが知られています。しかし、練習してみると、この 2 つは同時に使用できないことがわかりました。ant-design-vue テーブル内の編集可能なセルを動的にマージするソリューションを参照し、scopedSlots と CustomRender の間の競合が JSX 構文を通じて解決できることを確認します。
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",
},
];
},
},