封装Element UI中el-table表格为可配置列公用组件

Hi,我是前端人类学 (之前叫布兰妮甜)!

在现代前端开发中,表格是展示数据最常用的组件之一。Element UI的el-table功能强大,但在大型项目中直接使用会导致代码重复和维护困难。本文将探讨如何将el-table封装为可配置列的公用组件,提高开发效率和可维护性。


文章目录


一、为什么需要封装el-table?

  1. 减少重复代码:项目中多个表格往往有相似的列和功能
  2. 统一风格:确保整个项目的表格样式和行为一致
  3. 易于维护:修改表格功能只需调整一个组件
  4. 提高开发效率:通过配置快速生成表格,减少编码时间

二、设计思路

2.1 组件接口设计

公用表格组件应该提供清晰的接口:

  • columns:列配置数组,定义每列的属性
  • data:表格数据源
  • 支持el-table的所有原生属性和事件
  • 支持自定义列模板

2.2 列配置数据结构

javascript 复制代码
// 列配置示例
const columns = [
  {
    prop: 'name',          // 字段名
    label: '姓名',         // 列名
    width: '120',          // 列宽
    sortable: true,        // 是否可排序
    fixed: false,          // 是否固定
    align: 'center',       // 对齐方式
    // 自定义渲染函数
    render: (h, { row, index }) => {
      return h('span', `员工: ${row.name}`)
    }
  },
  // 更多列...
]

三、实现方案

3.1 基础封装

首先创建一个可接收列配置的表格组件:

html 复制代码
<template>
  <el-table
    :data="tableData"
    v-bind="$attrs"
    v-on="$listeners"
  >
    <template v-for="column in columns">
      <!-- 自定义列 -->
      <el-table-column
        v-if="column.render"
        :key="column.prop"
        v-bind="column"
      >
        <template slot-scope="scope">
          <!-- 使用render函数渲染自定义内容 -->
          <render-cell
            :render="column.render"
            :row="scope.row"
            :index="scope.$index"
          />
        </template>
      </el-table-column>
      
      <!-- 普通列 -->
      <el-table-column
        v-else
        :key="column.prop"
        v-bind="column"
      />
    </template>
    
    <!-- 默认插槽用于添加其他列 -->
    <slot />
  </el-table>
</template>

<script>
// 用于渲染自定义内容的组件
const RenderCell = {
  functional: true,
  props: {
    render: Function,
    row: Object,
    index: Number
  },
  render: (h, ctx) => {
    return ctx.props.render(h, ctx)
  }
}

export default {
  name: 'ConfigurableTable',
  components: { RenderCell },
  props: {
    columns: {
      type: Array,
      default: () => []
    },
    data: {
      type: Array,
      default: () => []
    }
  },
  computed: {
    tableData() {
      return this.data
    }
  }
}
</script>

3.2 高级功能扩展

在实际项目中,表格往往需要更多功能:

1. 支持分页

html 复制代码
<template>
  <div class="table-container">
    <el-table ... />
    
    <!-- 分页组件 -->
    <el-pagination
      v-if="showPagination"
      :current-page="currentPage"
      :page-size="pageSize"
      :total="total"
      @current-change="handlePageChange"
      layout="total, sizes, prev, pager, next, jumper"
    />
  </div>
</template>

2. 支持操作列

javascript 复制代码
// 在columns中添加操作列
{
  label: '操作',
  width: '150',
  actions: [
    {
      label: '编辑',
      icon: 'el-icon-edit',
      onClick: (row, index) => {
        this.handleEdit(row)
      }
    },
    {
      label: '删除',
      icon: 'el-icon-delete',
      type: 'danger',
      onClick: (row, index) => {
        this.handleDelete(row)
      }
    }
  ]
}

3. 支持动态列显示

javascript 复制代码
// 添加visible属性控制列显示
{
  prop: 'phone',
  label: '手机号',
  visible: true // 可通过外部条件控制显示/隐藏
}

四、使用示例

4.1 基本用法

html 复制代码
<template>
  <configurable-table
    :columns="columns"
    :data="tableData"
    stripe
    border
  />
</template>

<script>
export default {
  data() {
    return {
      columns: [
        {
          prop: 'name',
          label: '姓名',
          width: '120'
        },
        {
          prop: 'age',
          label: '年龄',
          sortable: true
        },
        {
          prop: 'address',
          label: '地址'
        }
      ],
      tableData: [
        { name: '张三', age: 25, address: '北京市海淀区' },
        { name: '李四', age: 30, address: '上海市浦东新区' }
      ]
    }
  }
}
</script>

4.2 带自定义渲染的用法

html 复制代码
<template>
  <configurable-table
    :columns="columns"
    :data="tableData"
  />
</template>

<script>
export default {
  data() {
    return {
      columns: [
        {
          prop: 'name',
          label: '姓名',
          render: (h, { row }) => {
            return h('div', [
              h('el-avatar', {
                props: {
                  size: 'small',
                  src: row.avatar
                }
              }),
              h('span', {
                style: { marginLeft: '10px' }
              }, row.name)
            ])
          }
        },
        {
          prop: 'status',
          label: '状态',
          render: (h, { row }) => {
            const type = row.status === '成功' ? 'success' : 'danger'
            return h('el-tag', {
              props: { type }
            }, row.status)
          }
        }
      ],
      tableData: [...]
    }
  }
}
</script>

通过封装Element UI的el-table为可配置列组件,我们实现了表格开发的标准化和高效化。这种封装不仅减少了重复代码,还提供了统一的扩展点,使表格功能更容易维护和升级。在实际项目中,可以根据具体需求进一步扩展此组件,如添加更复杂的筛选、导出、行列拖拽等功能。

相关推荐
jason_yang8 小时前
vue3自定义渲染内容如何当参数传递
前端·javascript·vue.js
gitboyzcf9 小时前
基于Taro4最新版微信小程序、H5的多端开发简单模板
前端·vue.js·taro
williamdsy9 小时前
实战复盘:pnpm Monorepo 中的 Nuxt 依赖地狱——Unhead 升级引发的连锁血案
vue.js·pnpm
冲!!9 小时前
vue3存储/获取本地或会话存储,封装存储工具,结合pina使用存储
前端·javascript·vue.js
BUG创建者9 小时前
uniapp vue页面传参到webview.nvue页面的html或者另一vue中
vue.js·uni-app·html
超人不会飛10 小时前
LLM应用专属的Vue3 Markdown组件 🚀重磅开源!
前端·javascript·vue.js
gogou10 小时前
在Vite项目中实现Excel快速导入数据到数据库
vue.js
眠りたいです10 小时前
基于脚手架微服务的视频点播系统-界面布局部分(二):用户界面及系统管理界面布局
c++·qt·ui·微服务·云原生·架构·cmake