面对产品的业务需求,我写了一个支持多个单元格展开的table组件

102 阅读3分钟

前言

大家好,我是你不会困,写代码就不会困,今天分享的是面对产品的业务需求,我写了一个支持多个单元格展开的table组件

最近工作上的一个需求,需要多个可展开的table组件,el-table支持一个:tree-props="{ children: 'children' }",这个是el-table支持树形展开,但是不支持多个展开,然后查了goolge等,也没有发现相关的demo,一时之间不知道怎么去实现~ image.png 展开第一级,部门下的小组级别 image.png 第二级别是季度可以展开,数据在子集上面 image.png

一开始的思路就是:tree-props="{ children: 'children' }"这个属性能不能支持到,然后查了半天也没有这种两个,尝试无果之后就放弃了

想了很久,一直被困在el-table是否支持,但是就是不支持,然后就想着自己写一个原生的table组件,但是周期会比较长,所以这个方法还是不行

突然有一个想法,之前可以通过遍历数组的形式来实现,那么这个表格也好像可以这样, 第一级还是使用:tree-props="{ children: 'children' }",第二级需要后端返回数据支持,也是返回一个list,然后在组件前面添加一个icon,点击展开和收起的效果,跟el-table自带的效果一样即可

这里是通过判断v-if,这里记得在后端返回数据的时候给tableList的每一个子项都添加一个字段isExpanded

<el-table-column prop="date" label="Date" width="180">
            <template slot-scope="{ row }">
              <div class="table-date">
                <div class="table-date-item">
                  <i
                    :class="
                      !row.isExpanded
                        ? 'el-icon-arrow-right'
                        : 'el-icon-arrow-down'
                    "
                    style="cursor: pointer; margin-right: 10px"
                    @click="row.isExpanded = !row.isExpanded"
                  ></i
                  >{{ row.date }}
                </div>
                <div v-for="item in row.dateList" :key="item.date">
                  <div v-if="row.isExpanded" class="table-date-items">
                    {{ item.date }}
                  </div>
                </div>
              </div>
            </template>

点击的时候置为true,就把对应得数据展示出来,这里可以考虑v-show,取决于你的tableList数据是不是很多

这里有个优化点,需要判断dateList的长度是不是大于0,如果为0就不要展示icon,要做好展位,保证table的样式一致

 tableData: [
        {
          id: 1,
          date: '2023Q1',
          name: '事业xx部',
          address: 'No. 189, Grove St, Los Angeles',
          children: [
            {
              id: 2,
              date: '2023Q1',
              name: 'xx一组',
              address: 'No. 189, Grove St, Los Angeles'
            }
          ],
          dateList: [
            {
              date: '202301',
              name: 'Tom',
              address: 'No. 189, Grove St, Los Angeles'
            },
            {
              date: '202302',
              name: 'Tom',
              address: 'No. 189, Grove St, Los Angeles'
            },
            {
              date: '202302',
              name: 'Tom',
              address: 'No. 189, Grove St, Los Angeles'
            }
          ],
          isExpanded: false,
          isShow: true
        },
        {
          id: 3,
          date: '2023-08-07',
          name: 'Jerry',
          address: 'No. 189, Grove St, Los Angeles',
          isShow: false
        },
        {
          id: 4,
          date: '2023-08-08',
          name: 'Spike',
          address: 'No. 189, Grove St, Los Angeles',
          isShow: true
        }
      ]

对应得样式穿透是将cell的padding去掉,给每一个遍历的row单元格加上上边框,去掉第一个的上边框,让其看起来是一个el-table的样式即可

<style lang="less" scoped>
.table-date {
  .table-item,
  .table-items,
  .table-date-item {
    height: 44px;
    line-height: 44px;
    padding: 0 10px;
  }
  .table-items {
    border-top: 1px solid #e6e6e6;
  }
  .table-date-items {
    height: 44px;
    padding-left: 45px;
    line-height: 44px;
    &:first-child {
      border-top: 1px solid #e6e6e6;
    }
  }
}

/deep/.el-table .cell {
  padding: 0px;
}
</style>

总结:

1.不要陷入el-table的使用规则中,有时候不适合业务开发,就要靠自己再次进行拓展

2.如果一时之间想不到解决方案,可以适当出去走走,换换脑子,说不定回来就想到解决方案

3.目前可以想到的就是这个方案,如果有更加好的实现方式可以在评论区说一下,大家一起学习进步