Bootstrap

Vue + ant design 实现嵌套子表格

Table - 嵌套子表格

一、效果展示

功能1:添加主表格一行
功能2:添加某个子表格一行
功能3:子表格数据的异步加载

在这里插入图片描述
在这里插入图片描述

二、代码实现

<template>
  <div>
    <a-button @click="add" type="primary" size="small" style="margin:20px">添加主表格数据</a-button>
    <a-table
      :columns="columns"
      :data-source="data"
      class="components-table-demo-nested"
      @expand="getInnerData"
      @expandedRowsChange="expandedRowsChange"
      style="margin:20px"
    >
      <a slot="operation" slot-scope="row" @click="addInnderData(row)">添加子表格数据</a>
      <a-table
        slot="expandedRowRender"
        slot-scope="inner"
        :columns="innerColumns"
        :data-source="inner.innerData"
        :pagination="false"
      >
        <span slot="operation" slot-scope="text" class="table-operation">
          <a-dropdown>
            <a-menu slot="overlay">
              <a-menu-item>Action 1</a-menu-item>
              <a-menu-item>Action 2</a-menu-item>
            </a-menu>
            <a>
              More
              <a-icon type="down" />
            </a>
          </a-dropdown>
        </span>
      </a-table>
    </a-table>
  </div>
</template>
<script>


const columns = [
  { title: 'Name', dataIndex: 'name', key: 'name' },
  { title: 'Sex', dataIndex: 'sex', key: 'sex' },
  { title: 'Age', dataIndex: 'age', key: 'age' },
  { title: 'Hobby', dataIndex: 'hobby', key: 'hobby' },
  { title: 'Action', key: 'operation', scopedSlots: { customRender: 'operation' } },
];

const innerColumns = [
  { title: 'Name', dataIndex: 'name', key: 'name' },
  { title: 'Sex', dataIndex: 'sex', key: 'sex' },
  { title: 'Age', dataIndex: 'age', key: 'age' },
  { title: 'Hobby', dataIndex: 'hobby', key: 'hobby' },
  {
    title: 'Action',
    dataIndex: 'operation',
    key: 'operation',
    scopedSlots: { customRender: 'operation' },
  },
];

export default {
  created() {
    this.init() // 获取主表格数据
  },
  data() {
    return {
      data: [],
      columns,
      innerColumns,
      expandedRowKeys: []
    };
  },
  methods: {
    /*
    * 功能:表格展开行的集合
    * 参数:expandedRowKeys:展开行的key形成的数组
    */
    expandedRowsChange(expandedRowKeys) {
      this.expandedRowKeys = expandedRowKeys
    },
    /*
   * 功能:加载主表格数据
   * 说明:此处采用键值对的形式,是为了避免全部子表格数据相同
   */
    init() {
      this.data.push({
        key: 0,
        name: '小红',
        sex: '女',
        age: '18',
        hobby: '唱歌',
        innerData: []
      }, {
        key: 1,
        name: '小明',
        sex: '男',
        age: '25',
        hobby: '打篮球',
        innerData: []
      }, {
        key: 2,
        name: '小兰',
        sex: '女',
        age: '15',
        hobby: '看书',
        innerData: []
      })
      console.log(this.data);
      console.log('主表格加载完');
    },
    /*
    * 功能:点击某行加号,加载子表格数据
    * 参数:expanded:是否展开 
    * 参数:record:点击行的数据
    */
    getInnerData(expanded, record) {
      if (expanded) { // 当展开子表格时,才会加载子表格数据
        if (record.key === 0) {
          this.data[0].innerData = [] // 因为我每次用的相同假数据,所以此处需要先清空。
          this.data[0].innerData.push({
            key: 11,
            name: '小白',
            sex: '女',
            age: '8',
            hobby: '看电影',
          }, {
            key: 12,
            name: '小黑',
            sex: '男',
            age: '36',
            hobby: '跑步',
          })
        } else if (record.key === 1) {
          this.data[1].innerData = [] // 因为我每次用的相同假数据,所以此处需要先清空。
          this.data[1].innerData.push({
            key: 21,
            name: '小刚',
            sex: '男',
            age: '28',
            hobby: '运动',
          }, {
            key: 22,
            name: '小白',
            sex: '女',
            age: '8',
            hobby: '看电影',
          })
        } else {
          this.data[2].innerData = [] // 因为我每次用的相同假数据,所以此处需要先清空。
          this.data[2].innerData.push({
            key: 31,
            name: '花花',
            sex: '男',
            age: '48',
            hobby: '收拾',
          }, {
            key: 32,
            name: '哦哦',
            sex: '男',
            age: '12',
            hobby: '吃饭',
          })
        }
      }
      console.log(this.data);
      console.log('加载子表格');
    },
    /*
    * 功能:添加主表格一行
    */
    add() {
      let i = this.data.length // 保证key唯一
      this.data.push({
        key: i,
        name: `${ i + 1 }`,
        sex: `${ i + 1 }`,
        age: '12',
        hobby: '吃饭',
        innerData: []
      })
    },
    /*
    * 功能:添加子表格一行
    * 参数:row:点击行的信息
    */
    addInnderData(row) {
      // 只有当这一行展开时,点击添加子表格才会有数据。
      if (this.expandedRowKeys.includes(row.key)) {
        let i = row.key * 10 + row.innerData.length + 1
        this.data.forEach(item => {
          if (item.key === row.key) {
            item.innerData.push({
              key: i,
              name: '哦哦',
              sex: '男',
              age: '12',
              hobby: '吃饭',
            })
          }
        })
      }
    }
  }
};
</script>

;