前端实战:基于Element Plus的CustomTable表格组件封装与应用

在中后台管理系统开发中,表格展示是高频需求,重复编写el-tableel-table-column不仅效率低下,还会导致代码冗余。本文将结合实际项目代码,从配置化思想出发,详解如何封装通用的CustomTable组件,并通过配置文件解耦表格结构,实现高效复用。

一、项目背景与目录结构

先梳理核心文件的位置和职责:

  • src/views/Dashboard/tableConfig.js:仪表盘页面的表格、搜索、表单配置文件,集中管理表格列、搜索项、编辑表单的结构化配置;
  • src/views/Message/tableConfig.js:消息页面的表格配置文件,复用相同的配置规范;
  • src/components/CustomTable/index.vue:通用表格组件封装核心文件,接收配置参数并渲染表格。

二、tableConfig配置文件解析

表格的列结构通过tableConfig数组配置化定义,先以Dashboard/tableConfig.js为例分析配置项设计:

1. 核心配置项说明

配置字段 类型 作用 示例
prop String 对应接口返回数据的字段名,与el-table-columnprop一致 prop: 'projectName'
label String 表格列的表头文字 label: '标题'
formatter Function 列数据格式化函数,接收行数据返回处理后的值 formatter: (row) => row + '个'
slot Boolean 是否为自定义插槽列(用于操作按钮等) slot: true
slotName String 自定义插槽名称,供父组件传递内容 slotName: 'handle'

2. 典型配置示例

javascript 复制代码
// Dashboard/tableConfig.js
export const tableConfig = [
    {
        prop: 'projectName',
        label: '标题'
    },
    {
        prop: 'createTime',
        label: '创建时间'
    },
    {
        prop: 'num',
        label: '数量',
        formatter: (row) => row + '个' // 数据格式化
    },
    {
        slot: true,
        label: '操作',
        slotName: 'handle' // 自定义插槽
    }
]

配置文件的核心价值是将表格结构与业务页面解耦,后续修改列顺序、新增列、调整格式,只需修改配置数组,无需改动页面和组件代码。

三、Dashboard/index.vue:CustomTable的使用

业务页面中只需引入配置文件,传递表格数据和配置给CustomTable,并通过插槽实现自定义列内容:

vue 复制代码
<template>
  <div class="dashboard-page">
    <!-- 通用表格组件 -->
    <CustomTable
      :tableData="tableData"
      :tableConfig="tableConfig"
      @handleEdit="handleEdit"
      @handleDelete="handleDelete"
    >
      <!-- 操作列自定义插槽 -->
      <template #handle="scope">
        <el-button size="small" type="primary" @click="handleEdit(scope.row)">编辑</el-button>
        <el-button size="small" type="danger" @click="handleDelete(scope.row)">删除</el-button>
      </template>
    </CustomTable>
  </div>
</template>

<script setup>
import { ref } from 'vue'
import CustomTable from '@/components/CustomTable/index.vue'
import { tableConfig } from './tableConfig.js'

// 模拟表格数据(实际从接口获取)
const tableData = ref([
  {
    projectName: 'XX项目',
    createTime: '2024-01-01',
    num: 10,
    // 其他字段...
  }
])

// 编辑事件
const handleEdit = (row) => {
  console.log('编辑', row)
}

// 删除事件
const handleDelete = (row) => {
  console.log('删除', row)
}
</script>

页面传递给CustomTable的核心参数/方法

名称 类型 作用
tableData Array 表格渲染的原始数据
tableConfig Array 表格列的配置数组(来自tableConfig.js)
自定义事件(如handleEdit) Function 父组件定义的业务方法,通过插槽传递给子组件触发

四、CustomTable组件核心封装实现

src/components/CustomTable/index.vue是封装核心,核心逻辑是循环tableConfig配置数组,动态渲染el-table-column,同时支持格式化、插槽等扩展能力。

完整代码实现

vue 复制代码
<template>
  <el-table
    :data="tableData"
    border
    stripe
    style="width: 100%"
    v-bind="$attrs" // 透传el-table的原生属性(如height、size等)
  >
    <!-- 循环渲染表格列 -->
    <template v-for="(item, index) in tableConfig" :key="index">
      <!-- 普通列(带格式化) -->
      <el-table-column
        v-if="!item.slot"
        :prop="item.prop"
        :label="item.label"
        align="center"
      >
        <template #default="scope">
          <!-- 支持数据格式化函数 -->
          {{ item.formatter ? item.formatter(scope.row[item.prop]) : scope.row[item.prop] }}
        </template>
      </el-table-column>

      <!-- 插槽列(自定义内容,如操作按钮) -->
      <el-table-column
        v-else
        :label="item.label"
        align="center"
      >
        <template #default="scope">
          <slot :name="item.slotName" :row="scope.row"></slot>
        </template>
      </el-table-column>
    </template>
  </el-table>
</template>

<script setup>
import { defineProps, useAttrs } from 'vue'

// 定义组件接收的Props
const props = defineProps({
  // 表格数据
  tableData: {
    type: Array,
    required: true,
    default: () => []
  },
  // 表格列配置
  tableConfig: {
    type: Array,
    required: true,
    default: () => []
  }
})

// 透传el-table的原生属性(如max-height、fit等)
const attrs = useAttrs()
</script>

<style scoped>
.el-table {
  --el-table-header-text-color: #333;
  --el-table-row-hover-bg-color: #f8f9fa;
}
</style>

封装核心要点

1. Props设计
  • tableData:接收父组件传递的表格数据源,类型为数组且必填;
  • tableConfig:接收列配置数组,与tableConfig.js的结构对应,实现列的动态渲染。
2. 动态渲染列
  • 普通列 :判断item.slotfalse时,渲染带prop的常规列,若配置了formatter则执行格式化函数处理数据;
  • 插槽列 :判断item.slottrue时,渲染自定义插槽列,通过slotName关联父组件的插槽,同时传递scope.row(行数据)给父组件,满足操作按钮获取行数据的需求。
3. 属性透传

通过v-bind="$attrs"将父组件传递的el-table原生属性(如heightsizemax-height等)透传给内部的el-table,提升组件的灵活性。

4. 样式与交互优化

通过scoped样式统一表格的表头文字颜色、行悬浮背景色,保持全局样式一致性。

五、组件复用与扩展

1. 多页面复用

Message/tableConfig.js定义了消息页面的表格配置,只需在Message/index.vue中引入CustomTable和对应的tableConfig,即可快速渲染表格:

vue 复制代码
<template>
  <CustomTable :tableData="messageData" :tableConfig="tableConfig">
    <template #detail="scope">
      <el-button size="small" @click="viewDetail(scope.row)">查看详情</el-button>
    </template>
  </CustomTable>
</template>

<script setup>
import CustomTable from '@/components/CustomTable/index.vue'
import { tableConfig } from './tableConfig.js'
// 其他逻辑...
</script>

2. 扩展能力

  • 支持更多格式化场景 :如时间格式化、状态枚举转换,只需在tableConfig中扩展formatter函数;
  • 支持自定义列宽 :在tableConfig中新增width字段,渲染时绑定到el-table-columnwidth属性;
  • 支持排序/筛选 :在tableConfig中新增sortable/filters字段,透传给el-table-column

六、封装价值与总结

1. 核心价值

  • 提效降本 :新增表格页面只需编写配置文件和业务逻辑,无需重复编写el-tableel-table-column
  • 易维护:表格结构修改只需调整配置文件,无需改动多个页面;
  • 统一规范:所有表格遵循相同的配置规范,团队协作更高效;
  • 高扩展性:通过插槽、格式化函数、属性透传,满足不同业务场景的定制化需求。

2. 总结

本文从实际项目出发,讲解了基于配置化思想的CustomTable组件封装流程:通过tableConfig.js集中管理表格列配置,业务页面传递数据和配置给CustomTable,组件内部循环配置动态渲染表格列,并支持格式化、插槽等扩展能力。这种封装方式既符合中后台系统"高复用、易维护"的需求,也体现了Vue组件化开发的核心思想。
Vue3 + Element Plus 实战:通用搜索组件CustomSearch封装与应用

相关推荐
天马37982 小时前
Canvas 倾斜矩形绘制波浪效果
开发语言·前端·javascript
天天向上10243 小时前
vue3 实现el-table 部分行不让勾选
前端·javascript·vue.js
qx093 小时前
esm模块与commonjs模块相互调用的方法
开发语言·前端·javascript
摘星编程4 小时前
在OpenHarmony上用React Native:SectionList吸顶分组标题
javascript·react native·react.js
0思必得04 小时前
[Web自动化] 爬虫之API请求
前端·爬虫·python·selenium·自动化
混迹在开发队伍里的伪开发4 小时前
css的var用法,定义属性,全局使用
前端·css
摘星编程5 小时前
React Native鸿蒙:ScrollView横向滚动分页实现
javascript·react native·react.js
摘星编程5 小时前
OpenHarmony + RN:TextInput密码强度检测
javascript·react native·react.js
雨季6665 小时前
构建 OpenHarmony 随机颜色生成器:用纯数学生成视觉灵感
开发语言·javascript·flutter·ui·ecmascript·dart