Vue+Elementui el-table组件二次封装

index.vue表格组件源码

<template>
  <div style="height: 100%;">
    <!-- 自定义头部标签操作按钮 -->
    <div style="padding: 3px 0;" v-if="headButton">
      <slot name="second"></slot>
    </div>
    <el-table v-loading="loading" :data="tableData" :row-key="rowKey" border @sort-change='sortChange' @select="select"
              :highlight-current-row="true" @select-all="select"
              @selection-change="handleSelectionChange"
              :header-cell-style="{'text-align':headerAlign,'background':'#eef1f6'}" @current-change="handleCurrentChange"
              :height="calcHeight"
              v-bind="$attrs"
              v-on="$listeners">
      <!-- v-bind="$attrs" 可以从外部直接使用el-table组件的属性值 -->
      <!-- v-on="$listeners" 可以从外部直接调用el-table组件的方法 -->
      <el-table-column type="selection" v-if="choice" width="50" :align="headerAlign" :key="Math.random()">
      </el-table-column>
      <!-- 序号 -->
      <el-table-column label="序号" v-if="serialNumber" fixed="left" width="50" type="index" :align="headerAlign"
                       :key="Math.random()">
      </el-table-column>
      <!-- 动态表头 -->
      <template v-for="(item, index) in tableLabel">
        <el-table-column
          :key="index"
          :prop="item.prop"
          :label="item.label"
          :align="item.align?item.align:'left'"
          :formatter="item.render"
          :show-overflow-tooltip="item.tooltip || false"
          :fixed="item.fixed"
          :index="index"
          :width="item.width"
          :sortable="item.sort"
        >
          <!-- 动态具名插槽 -->
          <div v-if="item.slot" slot-scope="scope">
            <slot :name="item.prop" :row="scope.row"></slot>
          </div>
          <!-- 处理render函数 -->
          <div v-else-if="item.render" slot-scope="scope">
            {{item.render(scope.row)}}
          </div>
          <div v-else slot-scope="scope">
            {{scope.row[item.prop]}}
          </div>
        </el-table-column>
      </template>
    </el-table>

  </div>
</template>

<!-- /**
 * 组件说明
 * 属性:
 * 参数                     说明                           类型                    默认值
 * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 * tableData              列表 的数据源                   Array                      []
 * treeProps              支持树类型的数据的列表显示       Object                     {children: 'children'}
 * rowKey                 树类型的数据 列表必须要指定        String                     '_id'
 * serialNumber           是否需要序号                     Boolean                    true
 * headerAlign               表头对齐方式/复选框/序号              String                    'left'/'center'/'right'
 * tableLabel               动态表头渲染数组                Array                     []
 * choice                   是否开启多选复选框                Boolean                 false
 * operation               操作列表按钮                    Object                     {}
 * total                   分页总页数                     number                     0

 * 回调事件:
 * select  获取复选框选中对象 返回数组
 * sortChange     获取当前点击表头指定排序结果
 * handleCurrentPage     每次切换页数触发并且回调页数
 * handleNumberChange     每次切换展示的条数触发并且回调
 */ -->
<script>
  export default {
    components: {

    },
    props: {
      headButton: {
        type: Boolean,
        default: false
      },
      tableData: {
        type: Array,
        default: () => ([])
      },
      treeProps: {
        type: Object,
        default: () => ({
          children: 'children'
        })
      },
      rowKey: {
        type: String,
        default: 'id'
      },
      calcHeight:{
        type: String,
        default: 'calc(100vh - 200px)'
      },
      serialNumber: {
        type: Boolean,
        default: false
      },
      headerAlign: {
        type: String,
        default: 'left'
      },
      tableLabel: {
        type: Array,
        default: () => ([])
      },
      loading:{
        type: Boolean,
        default: true
      },
      choice: {
        type: Boolean,
        default: false
      },
      operation: {
        type: Object,
        default: () => ({})
      },
      total: {
        type: Number,
        default: 0
      },

    },
    data() {
      return {
      }
    },
    watch: {
    },
    created() {
    },
    methods: {
      // 复选框勾选
      select(row) {
        this.$emit('select', row)
      },
      // 排序
      sortChange(column, prop, order) {
        this.$emit('sortChange', column)
      },
      // 点击列表 获取数据
      handleCurrentChange(row) {
        this.$emit('handleCurrentChange', row)
      },

      handleSelectionChange(row){
        this.$emit('handleSelectionChange', row)
      }
    }
  }
</script>
<style scoped lang="scss">
  /* 默认el-table 行高过于高,这里设置减少padding之间的间距 */
  ::v-deep th {
    padding: 2px 0;
  }

  ::v-deep .el-table td {
    padding: 5px 0;
  }
</style>

使用示例

父组件里面

自定义列可以使用插槽 列数据格式展示可以使用render函数

    <table-list :loading="loading" :tableData="myProcessList" :tableLabel="tableLabel" :choice="true" pagingPosition="center" :paging="true"
                :operation="operation" :calcHeight="calcHeight" :fixedHeight="500" :total="total" headerAlign='center'
                 :headButton="true" @handleCurrentChange="handleCurrentChange" @handleSelectionChange="handleSelectionChange">
<!--      <template v-slot:second>-->
<!--        <el-button type="primary" size="mini" ><i class="el-icon-download"></i> 导出</el-button>-->
<!--      </template>-->
      <template slot-scope="scope" slot="ticketCode">
        <div @click="handleFlowRecord(scope.row)" style="color:#1890ff;cursor:pointer;">{{scope.row.finishTime==null ?scope.row.procVars && scope.row.procVars.ticketCode || ('LC'+'_'+scope.row.procVars.procDefId && scope.row.procVars.procDefId.split(":")[0]+'_'+scope.row.taskId) :scope.row.startUserId || ''}}</div>
      </template>
      <template slot-scope="scope" slot="category">
        <dict-tag :options="dict.type.sys_process_category" :value="scope.row.category" />
      </template>
      <template slot-scope="scope" slot="version">
        <el-tag size="medium">v{{ scope.row.procDefVersion }}</el-tag>
      </template>
      <template slot-scope="scope" slot="ticketAbstract">
        <div v-if="scope.row.procVars.ticketAbstract!=='' && scope.row.procVars.ticketAbstract!==null && typeof(scope.row.procVars.ticketAbstract) !== 'undefined'" @click="handleFlowRecord(scope.row)" style="color: #1890ff; cursor: pointer">
          <div v-if="scope.row.procDefName.indexOf('操作票')>-1"><el-tag type="success" size="mini">操作任务:</el-tag> {{ scope.row.procVars.ticketAbstract || '' }}</div>
          <div v-else-if="scope.row.procDefName.indexOf('缺陷')>-1 && !scope.row.procVars.ticketAbstract === false"><el-tag type="danger" size="mini">缺陷详情:</el-tag>&nbsp;<el-tag type="info" size="mini" v-if="!scope.row.procVars.departmentShould === false">{{scope.row.procVars.departmentShould}}</el-tag> {{ scope.row.procVars.ticketAbstract || '' }}</div>
          <div v-else-if="scope.row.procDefName.indexOf('工作票')>-1"><el-tag type="waring" size="mini">工作内容:</el-tag> {{ scope.row.procVars.ticketAbstract || '' }}</div>
        </div>
        <div v-else> 暂无内容 </div>
      </template>
      <template slot-scope="scope" slot="flowStatus">
        <el-tag v-if="scope.row.finishTime == null" size="mini">进行中</el-tag>
        <el-tag type="success" v-else size="mini">已完成</el-tag>
      </template>
      <template slot-scope="scope" slot="workName">
        <label v-if="scope.row.assigneeName"
        >{{ scope.row.assigneeName }}
          <el-tag type="info" size="mini" v-if="!scope.row.assigneeDeptName === false">{{ scope.row.assigneeDeptName }}</el-tag></label
        >
      </template>
      <template slot-scope="scope" slot="handleButton">
        <el-button @click="handleFlowRecord(scope.row)" icon="el-icon-view" type="text" size="small">详情</el-button>
        <el-button
          @click="handleDelete(scope.row)"
          type="text"
          size="small"
          icon="el-icon-delete"
          v-hasPermi="['system:deployment:remove']"
        >删除</el-button
        >
      </template>
    </table-list>

表格数据:

      tableLabel:[
        {
          prop: 'ticketCode',
          label: '流程编号',
          align:'left',
          sort:true,
          fixed:true,
          slot:'ticketCode',
          width:180
        },
        {
          prop: 'procDefName',
          label: '流程名称',
          align: 'left',
          tooltip:true,
          width:260
        },
        {
          prop: 'category',
          label: '流程分类',
          align: 'center',
          sort:true,
          width:150,
          slot:'category'
        },
        {
          prop: 'ticketAbstract',
          label: '内容摘要',
          align: 'left',
          slot: "ticketAbstract",
          width:260,
          tooltip:true
        },
        {
          prop: 'version',
          label: '流程版本',
          align: 'center',
          slot:'version',
          width:90
        },
        {
          prop: 'createTime',
          label: '提交时间',
          align: 'center',
          width:180
        },
        {
          prop: 'flowStatus',
          label: '流程状态',
          align: 'center',
          slot: "flowStatus",
          width:100,
        },
        {
          prop: 'duration',
          label: '耗时',
          align: 'center',
          width:150
        },
        {
          prop: 'taskName',
          label: '当前进度',
          align: 'center',
          width:100,
          tooltip:true
        },
        {
          prop: 'workName',
          label: '办理人',
          align: 'left',
          width:150,
          tooltip:true,
          slot:'workName',
        },
        {
          prop: 'handleButton',
          label: '操作',
          align: 'center',
          width:150,
          fixed:'right',
          slot:'handleButton',
        }
      ],
相关推荐
Watermelo6174 分钟前
详解js柯里化原理及用法,探究柯里化在Redux Selector 的场景模拟、构建复杂的数据流管道、优化深度嵌套函数中的精妙应用
开发语言·前端·javascript·算法·数据挖掘·数据分析·ecmascript
一个处女座的程序猿O(∩_∩)O2 小时前
小型 Vue 项目,该不该用 Pinia 、Vuex呢?
前端·javascript·vue.js
燃先生._.8 小时前
Day-03 Vue(生命周期、生命周期钩子八个函数、工程化开发和脚手架、组件化开发、根组件、局部注册和全局注册的步骤)
前端·javascript·vue.js
高山我梦口香糖9 小时前
[react]searchParams转普通对象
开发语言·前端·javascript
black^sugar10 小时前
纯前端实现更新检测
开发语言·前端·javascript
2401_8576009511 小时前
SSM 与 Vue 共筑电脑测评系统:精准洞察电脑世界
前端·javascript·vue.js
2401_8576009511 小时前
数字时代的医疗挂号变革:SSM+Vue 系统设计与实现之道
前端·javascript·vue.js
GDAL11 小时前
vue入门教程:组件透传 Attributes
前端·javascript·vue.js
小白学大数据11 小时前
如何使用Selenium处理JavaScript动态加载的内容?
大数据·javascript·爬虫·selenium·测试工具