vue3.0+antd实现嵌套子表格一键全部展开的功能

1.页面上显示出一键全部展开的列

antd本身有嵌套子表格功能,用expandedRowRender就可以实现,但没有一键全部展开的功能,且在使用expandedRowRender时自动生成的展开按钮列也是无法选中进行自行编辑的(也可能是我没找到),所以此处先将这个自动展开列去除,再自己写按钮操作列。
在这里插入图片描述
》》》
在这里插入图片描述
此处使用的属性是:expandRowByClick=‘true’(可点击行展开)和:expandIconColumnIndex=“-1”(隐藏展开按钮列)
》》》
在这里插入图片描述
网上有教程说设置expandiconascell = ‘fasle’来隐藏按钮列的,并没有生效,四处查找后发现那些教程中用的都是2.x.x版本的antd,那么应该是antd更新到新的某个版本之后这个属性就不再生效了。

》》》之后再自定义一列按钮列就非常简单了
着急吃饭懒得调整样式了
在这里插入图片描述

在这里插入图片描述

body部分的template同理。

在新写的按钮上实现功能

在这里插入图片描述
通过设置expandRowKeys和expandedRowChange属性,实现对展开方法的控制,以下是全部代码:

<template>
  <a-table
    :columns="columns"
    :data-source="data"
    :expandRowByClick="true"
    :expandIconColumnIndex="-1"
    :expandedRowKeys="expRowKeys"
    @expandedRowsChange="expandedRowsChange"
    class="components-table-demo-nested"
  >
    <template #headerCell="{ column }">
      <template v-if="column.key === 'expRows'">
        <a-button v-if="expRowKeys.length === 0" @click="expandAllRows(true)">
          <a-tooltip placement="top">
            <template #title> 展开全部 </template>
            <PlusSquareOutlined />
          </a-tooltip>
        </a-button>
        <a-button v-else @click="expandAllRows(false)">
          <a-tooltip placement="top">
            <template #title> 收起全部 </template>
            <MinusSquareOutlined />
          </a-tooltip>
        </a-button>
      </template>
    </template>
    <template #bodyCell="{ column, record }">
      <template v-if="column.key === 'operation'">
        <a>Publish</a>
      </template>
      <template v-if="column.key === 'expRows'">
        <a-button v-if="expRowKeys.indexOf(record.key) === -1">
          <PlusCircleOutlined />
        </a-button>
        <a-button v-else>
          <MinusCircleOutlined />
        </a-button>
      </template>
    </template>
    <template #expandedRowRender>
      <a-table
        :columns="innerColumns"
        :data-source="innerData"
        :pagination="false"
      >
        <template #bodyCell="{ column }">
          <template v-if="column.key === 'state'">
            <span>
              <a-badge status="success" />
              Finished
            </span>
          </template>
          <template v-else-if="column.key === 'operation'">
            <span class="table-operation">
              <a>Pause</a>
              <a>Stop</a>
              <a-dropdown>
                <template #overlay>
                  <a-menu>
                    <a-menu-item>Action 1</a-menu-item>
                    <a-menu-item>Action 2</a-menu-item>
                  </a-menu>
                </template>
                <a>
                  More
                  <down-outlined />
                </a>
              </a-dropdown>
            </span>
          </template>
        </template>
      </a-table>
    </template>
  </a-table>
</template>
<script>
import {
  DownOutlined,
  PlusCircleOutlined,
  MinusCircleOutlined,
  PlusSquareOutlined,
  MinusSquareOutlined,
} from "@ant-design/icons-vue";
import { defineComponent, ref } from "vue";
const columns = [
  {
    title: "",
    dataIndex: "expRows",
    key: "expRows",
  },
  {
    title: "Name",
    dataIndex: "name",
    key: "name",
  },
  {
    title: "Platform",
    dataIndex: "platform",
    key: "platform",
  },
  {
    title: "Version",
    dataIndex: "version",
    key: "version",
  },
  {
    title: "Upgraded",
    dataIndex: "upgradeNum",
    key: "upgradeNum",
  },
  {
    title: "Creator",
    dataIndex: "creator",
    key: "creator",
  },
  {
    title: "Date",
    dataIndex: "createdAt",
    key: "createdAt",
  },
  {
    title: "Action",
    key: "operation",
  },
];
const data = [];

for (let i = 0; i < 3; ++i) {
  data.push({
    key: i,
    name: `Screem ${i + 1}`,
    platform: "iOS",
    version: "10.3.4.5654",
    upgradeNum: 500,
    creator: "Jack",
    createdAt: "2014-12-24 23:12:00",
  });
}
const expRowKeys = ref([]);
const expandedRowsChange = (val) => {
  expRowKeys.value = val;
};
const expandAllRows = (val) => {
  if (val) {
    // 全部展开
    const expandRows = [];
    for (const i in data) {
      expandRows.push(data[i].key);
    }
    expandedRowsChange(expandRows);
  } else {
    // 全部收回
    expandedRowsChange([]);
  }
};

const innerColumns = [
  {
    title: "Date",
    dataIndex: "date",
    key: "date",
  },
  {
    title: "Name",
    dataIndex: "name",
    key: "name",
  },
  {
    title: "Status",
    key: "state",
  },
  {
    title: "Upgrade Status",
    dataIndex: "upgradeNum",
    key: "upgradeNum",
  },
  {
    title: "Action",
    dataIndex: "operation",
    key: "operation",
  },
];
const innerData = [];

for (let i = 0; i < 3; ++i) {
  innerData.push({
    key: i,
    date: "2014-12-24 23:12:00",
    name: `This is production name ${i + 1}`,
    upgradeNum: "Upgraded: 56",
  });
}

export default defineComponent({
  components: {
    DownOutlined,
    PlusCircleOutlined,
    MinusCircleOutlined,
    PlusSquareOutlined,
    MinusSquareOutlined,
  },

  setup() {
    return {
      data,
      columns,
      innerColumns,
      innerData,
      expRowKeys,
      expandedRowsChange,
      expandAllRows,
    };
  },
});
</script>


题外话

在做这个全部展开的需求的时候碰到另外一个问题:我的表格data-source是后端获取来的,前端找不到合适的切入点去拿取数据,expandedRowsChange方法是需要获取每条数据的key,将之赋值给expRowKeys来实现全部展开。但是antd的table也没有提供点击获取整个表格数据的方法,给多层嵌套带来了一点麻烦。解决办法是将嵌套部分的表格做成子组件引用,以props的形式把后端传来的数据传递给子组件,就可以在子组件内部获取到data-source数据。

Logo

前往低代码交流专区

更多推荐