Loading

vue2实现el-table-column多级效果

背景

有的时候我们表格的列可能是多级的情况,但是如果采用官方的示例,需要循环嵌套。

  1. 支持多层嵌套
  2. 某列支持插槽

效果图

代码

App.vue

<template>
  <div class="app">
    <sys-table :tableColumns="table_columns" :data="table_data">
      <template #address="scope">
        <h1>嘻嘻:{{ scope.row.address }}</h1>
      </template>
    </sys-table>
  </div>
</template>

<script>
export default {
  data() {
    return {
      headerCellStyle: {
        backgroundColor: 'orange',
        color: '#fff',
      },
      table_columns: [
        {
          label: '姓名',
          prop: 'name',
        },
        {
          label: '年龄',
          prop: 'age',
        },
        {
          label: '住址',
          prop: 'address',
          slotFlag: true,
        },
        {
          label: '朋友-1',
          children: [
            {
              label: '朋友A',
              prop: 'friend_a',
            },
            {
              label: '朋友B',
              prop: 'friend_b',
            },
          ],
        },
        {
          label: '朋友-2',
          children: [
            {
              label: '朋友-2A',
              prop: 'friend_2_a',
              children: [
                {
                  label: '朋友-3A',
                  prop: 'friend_3a',
                },
              ],
            },
            {
              label: '朋友-2B',
              prop: 'friend_2_b',
            },
          ],
        },
      ],
      table_data: [],
    }
  },
  created() {
    setTimeout(() => {
      this.table_data = [
        {
          name: '小明',
          age: 23,
          address: '光明路',
          friend_a: 'a1',
          friend_b: 'b1',
        },
      ]
    }, 300)
  },
}
</script>

<style lang="less" scoped></style>

sys-table.vue

<template>
  <div class="sys-table">
    <el-table border v-bind="$attrs">
      <sys-table-column
        v-for="item in tableColumns"
        :key="item.prop"
        :col="item"
      >
        <!-- 动态插槽 -->
        <template v-for="slot in Object.keys($scopedSlots)" #[slot]="scope">
          <!-- 以之前的名字命名插槽,同时把数据原样绑定 -->
          <slot :name="slot" v-bind="scope" />
        </template>
      </sys-table-column>
    </el-table>
  </div>
</template>

<script>
import SysTableColumn from './sys-table-column.vue'
export default {
  components: {
    SysTableColumn,
  },
  props: {
    tableColumns: {
      type: Array,
    },
  },
}
</script>

<style lang="less" scoped></style>

sys-table-column.vue

<template>
  <el-table-column
    v-if="!col.children"
    :label="col.label"
    :prop="col.prop || ''"
    :show-overflow-tooltip="!col.els"
  >
    <template #header>
      <slot v-if="col.headerSlot" :name="col.headerSlot" />
      <span v-else>{{ col.label }}</span>
    </template>
    <template #default="scope">
      <slot v-if="col.slotFlag" :name="col.prop" :row="scope.row" />
      <span v-else>{{
        typeof scope.row[col.prop] !== 'number' && !scope.row[col.prop]
          ? '--'
          : scope.row[col.prop]
      }}</span>
    </template>
  </el-table-column>

  <el-table-column v-else :label="col.label">
    <sys-table-column v-for="t in col.children" :key="t.prop" :col="t">
      <!-- 注意:如果是vue2中的话customSlots可以替换为$scopedSlots,而且下面setup中的取值也不需要了 -->
      <template v-for="slot in Object.keys($scopedSlots)" #[slot]="scope">
        <!-- 以之前的名字命名插槽,同时把数据原样绑定 -->
        <slot :name="slot" v-bind="scope" />
      </template>
    </sys-table-column>
  </el-table-column>
</template>

<script>
export default {
  name: 'SysTableColumn',
  props: {
    // columns: Array,
    col: {
      type: Object,
      default: () => {},
    },
  },
  data() {
    return {}
  },
}
</script>

<style lang="less" scoped></style>

参考文档

https://blog.csdn.net/qq_16844491/article/details/116064593

posted @ 2025-05-24 23:50  ^Mao^  阅读(73)  评论(0)    收藏  举报