vue3封装深度的table-column

363 阅读1分钟

前言

第一次发文,如有不足请见谅。项目中,不免会需要联动,有个项目就是需要有设置弹窗和表格进行联动,普通的直接写table-column书写方式肯定是不行的, 就想着使用数组的形式进行数据储存,这样进行操作也方便,数组形式对于我们肯定是不陌生的。

使用的项目技术栈

  • vue3
  • element-plus

查了一些示例,就发现了单层的表格,确没有多层表格的一些实现,就自己试着探索一下,封装了一个遍历的组件。希望有问题的朋友少走点弯路。

数据

// hidden 是做隐藏效果
const columns = [
  {
    title: '国家',
    key: 'country',
    minWidth: '130',
    fixed: true
  },
  {
    title: '货币',
    key: 'money',
    minWidth: '130',
    hidden: false,
    children: [
      {
        title: '人民币',
        key: 'CNY',
        minWidth: '130',
        hidden: false
      },
      {
        title: '美元',
        key: 'dollar',
        minWidth: '130',
        hidden: false
      }
    ]
  }
]

封装的遍历组件

<template>
  <el-table-column
    v-if="!item.hidden"
    :key="item.key"
    :label="item.title"
    :type="item.type"
    :fixed="item.fixed"
    :min-width="item.minWidth"
    :prop="item.key"
    :class-name="item.className"
  >
    <!-- 多层遍历 -->
    <DeepTableColumn
      v-for="inItem in item.children"
      :key="inItem.key || inItem.title"
      :item="inItem"
    >
      <template #default="scope">
        <slot v-bind="{ ...scope, inItem: inItem }"></slot>
      </template>
    </DeepTableColumn>
    <template v-if="!item.children?.length" #default="scope">
      <slot v-bind="{ ...scope, innerItem: item }"></slot>
    </template>
    <!-- 头部如需定制,可额外添加 -->
    <template #header>
      <span>{{ item.title }}</span>
    </template>
  </el-table-column>
</template>
<script lang="ts" setup>
// 进行遍历的table-column
defineOptions({
  name: 'DeepTableColumn'
})
interface DataProps {
  item: {
    key: string
    title: string
    type?: string
    fixed?: boolean
    minWidth?: number | string
    align?: string
    [key: string]: any
    children: {
      key: string
      title: string
      type: string
      fixed?: boolean
      minWidth?: number | string
    }[]
  }
}

defineProps<DataProps>()
</script>

使用

我们直接进行数据使用

  <el-table
    ref="tableRef"
    :data="[
      {
        country: 'CC',
        CNY: '100',
        dollar: '10'
      },
      { country: 'BB', CNY: '50', dollar: '50' }
    ]"
    style="width: 100%; padding: 20px"
    :border="false"
  >
    <!-- 可以针对key进行定制化的需求 -->
    <DeepTableColumn v-for="item in columns" :key="item.key || item.title" :item="item">
      <template #default="{ row, innerItem, $index }">
        <template v-if="innerItem.key === 'CNY'">
          <span style="color: red">{{ row[innerItem.key] }}</span>
        </template>
        <template v-else>
          {{ row[innerItem.key] }}
        </template>
      </template>
    </DeepTableColumn>
  </el-table>

最后的效果

image.png

结语

感谢各位观看,如有问题请指正。