Ant vue テーブルのテーブルデータの動的マージ

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",
        },
      ];
    },

参考記事: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 は動的に結合されたセルをカスタマイズできることが知られています。しかし、練習してみると、この 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",
        },
      ];
    },
  },

効果を達成する

ここに画像の説明を挿入

おすすめ

転載: blog.csdn.net/qq_46258819/article/details/127298168