效果图

核心代码,封装成单独的组件,持续复用

appElTableMultistage.vue

<template>
  <el-table :data="tableData" @row-click="rowClick">
    <el-table-column v-if="isSelection"
                     type="selection"
                     width="55">
    </el-table-column>
    <template v-for="item in tableHeader">
      <TableColumn v-if="item.children && item.children.length"
                    :key="item.id"
                    :coloumn-header="item"
                    :row-id="rowId" />
      <el-table-column :key="item.id"
                       v-else
                       :label="item.label"
                       :prop="item.prop" />
    </template>
  </el-table>
</template>

<script lang="ts" setup>
import TableColumn from './tableColumn.vue'
import { defineProps, defineEmits, ref} from 'vue'
const props = defineProps({
  tableData: {
    type: Array,
    required: true,
  },
  // 多级表头的数据
  tableHeader: {
    type: Array,
    required: true,
  },
  isSelection: {
    type: Boolean,
    default: false,
  },
})
let rowId: string = ref('')
const rowClick = (row: any) => {
  rowId.value = row.id
}
</script>

这是第二个组件,需要在第一个组件里面引入的,主要是处理多级表头

 name="TableColumn"很重要,name和文件名得一样,不然多级表头就会出不来

tableColumn.vue

<template>
  <el-table-column :label="coloumnHeader.label"
                   :prop="coloumnHeader.label"
                   align="center">
    <template v-for="item in coloumnHeader.children">
      <tableColumn v-if="item.children && item.children.length"
                   :key="item.id"
                   :coloumn-header="item" />
      <el-table-column :key="item.name"
                       v-else
                       :label="item.label"
                       :prop="item.prop"
                       align="center"
                       width="80px">
      </el-table-column>
    </template>
  </el-table-column>
</template>

<script lang="ts" setup name="TableColumn">
import { defineProps, defineEmits, ref, inject } from 'vue'
const props = defineProps({
  coloumnHeader: {
    type: Object,
    required: true,
  },
  rowId: {
    type: Number,
    required: true,
  },
})
</script>

使用

app.vue

<template>
    <div>
        <app-el-table-multistage
            :table-data="form.giftsTableData"
            :table-header="tableHeaderConfig"
            :isSelection="isRejected"
          />
    </div>
</template>
<script lang="ts" setup>
import { reactive, ref} from 'vue'
// 记得把表格组件引入
import AppElTableMultistage from "./components/appElTableMultistage.vue"

// 表头
let tableHeaderConfig = reactive([
  {
    id: 100,
    label: '一级表头',
    prop: 'date',
  },
  {
    id: 200,
    label: '一级表头',
    prop: 'date',
  },
  {
    id: 300,
    label: '一级表头',
    prop: 'date',
  },
  {
    id: 400,
    label: '一级表头',
    prop: '',
    children: [
      {
        id: 401,
        label: '二级表头',
        prop: '',
        children: [
          {
            id: 402,
            label: '三级表头',
            prop: 'name',
          },
          {
            id: 402,
            label: '三级表头',
            prop: 'name',
          },
          {
            id: 403,
            label: '三级表头',
            prop: 'phone',
          },
        ],
      },
      {
        id: 401,
        label: '二级表头',
        prop: '',
        children: [
          {
            id: 402,
            label: '三级表头',
            prop: 'name',
          },
          {
            id: 402,
            label: '三级表头',
            prop: 'name',
          },
        ],
      },
    ],
  },
  {
    id: 404,
    label: '二级表头',
    prop: 'state',
  },
])
// 是否展示多选框
let isRejected: boolean = ref(true)
// 表格数据
let form = reactive({
    giftsTableData: Array.from(new Array(3), (_, i) => ({
        id: i,
        date: '档次' + (i + 1),
        name: i,
        phone: i,
        province: 0,
        city: 0,
        state: 0,
        number: 1,
      })),
})
</script>

注:vue2写法和vue3大差不差,把vue3的写法转成vue2就可以,整体架子是一样的

Logo

前往低代码交流专区

更多推荐