vue——组件之elementTable组件再封装

首先先上代码,下面是一个vue类型的文件,代码如下

<template>
  <div class="tl-rl">
    <template :table="table">
      <el-table
        v-loading="table.loading"
        :show-summary="table.hasShowSummary"
        :summary-method="table.getSummaries"
        ref="TlRlTable"
        :data="table.data"
        tooltip-effect="dark"
        :border="table.border"
        style="width: 100%"
        :row-class-name="rowClassName"
        :span-method="objectSpanMethod"
        header-row-class-name="thClassName"
        @selection-change="handleSelectionChange"
        @row-click="rowClick">
        <el-table-column
          v-if="table.hasSelect"
          type="selection"
          width="55">
        </el-table-column>
        <el-table-column type="expand" v-if="table.hasExpand">
          <template slot-scope="props">
            <el-form label-position="left" inline class="demo-table-expand">
              <el-form-item :label="item.label" v-for="item in table.expands" :key="item.id">
                <span>{{ props.row[item.prop] }}</span>
              </el-form-item>
            </el-form>
          </template>
        </el-table-column>
        <!--<el-table-column-->
          <!--v-for="item in table.tr"-->
          <!--v-if="item.show === false ? item.show : true"-->
          <!--:label="item.label"-->
          <!--:prop="item.prop"-->
          <!--:class-name="item.className ? item.className : ''"-->
          <!--:key="item.id"-->
          <!--:width="item.width ? item.width : ''"-->
          <!--:min-width="item.minWidth ? item.minWidth : ''">-->
        <!--</el-table-column>-->
        <template v-for="item in table.tr">
          <el-table-column
            v-if="item.show !== false && item.show === 'template'"
            :label="item.label"
            :class-name="item.className ? item.className : ''"
            :key="item.id"
            :width="item.width ? item.width : ''"
            :min-width="item.minWidth ? item.minWidth : ''" >
            <template slot-scope="scope">
              <slot :name="item.prop" :obj="scope"></slot>
            </template>
          </el-table-column>
          <el-table-column
            v-else-if="item.show !== false && item.show !== 'template'"
            :label="item.label"
            :prop="item.prop"
            :class-name="item.className ? item.className : ''"
            :key="item.id"
            :width="item.width ? item.width : ''"
            :min-width="item.minWidth ? item.minWidth : ''" >
          </el-table-column>
        </template>
        <el-table-column
          column-key="operation"
          :label="table.operation.label"
          :width="table.operation.width ? table.operation.width : ''"
          :min-width="table.operation.minWidth ? table.operation.minWidth : ''"
          :class-name="table.operation.className"
          v-if="table.hasOperation">
          <template slot-scope="scope">
            <el-button
              v-for="item in table.operation.data"
              :class="item.classname ? item.classname : ''"
              :key="item.id"
              :size="item.size"
              @click.stop="handleOperation(scope.$index, scope.row, item.id)">{{ item.label }}</el-button>
          </template>
        </el-table-column>
      </el-table>
    </template>
  </div>
</template>

<script>
  export default {
    name: 'recordlist',
    props: {
      table: {
        type: Object,
        default() {
          return {
            hasMergeRowOrColumn: false, // 是否合并单元格
            loading: false,          // 加载中动画
            hasShowSummary: false,   // 是否显示表位合计行
            border: false,           // 是否带有纵向边框,默认为false
            hasSelect: false,        // 有无选中功能
            hasOperation: false,     // 有无操作功能
            hasExpand: false,        // 有无展开行功能
            tr: [                    // 表头数据 —— className:列的class名
              {
                id: '1',
                label: 'label',
                prop: 'prop',
                className: 'classname',
                minWidth: '80',
                show: true           // show有三种值:false隐藏当前列,true常规表格列,template自定义表格列
//          <template slot-scope="props" slot="example">
//                <a class="list-a" target="_blank" :href="'/#/bombscreen?mobile=' + props.obj.row.mobile">{{ props.obj.row.username }}</a>
//          </template>
              }
            ],
            data: [],                // 表格数据 —— 如需添加行class,处理数据时则需要传入class名, class需为数组
            operation: {             // 操作功能
              label: '操作',                // 操作列的行首文字
              width: '200',                // 操作列的宽度
              className: '',               // 操作列的class名
              data: [                      // 操作列数据
                {
                  label: '通过',                // 按钮文字
                  Fun: 'handleSubmit',         // 点击按钮后触发的父组件事件
                  size: 'mini',                // 按钮大小
                  id: '1',                     // 按钮循环组件的key值
                  classname: 'show'            // 按钮的类名
                }
              ]
            },
            expands: [               // 展开行数据
              {
                id: '1',
                label: 'label',
                prop: 'prop'
              }
            ],
            getSummaries(param) {               // 自定义表位合计行数据
              // *** 此函数传入param参数
              console.log(param);
              // *** 最后返回一个数组,合计行会显示数组中的内容
              return []
            }
          }
        }
      }
    },
    methods: {
      handleSelectionChange(val) {
        this.$emit('onHandleSelectionChange', val);
      },
      handleOperation(a, b, id) {
        const data = this.table.operation.data;
        for (let i = 0; i < data.length; i++) {
          if (id === data[i].id) {
            this.$emit(data[i].Fun, a, b);
          }
        }
      },
      objectSpanMethod({ row, column, rowIndex, columnIndex }) {
        if (!this.hasMergeRowOrColumn) {
          return
        } else {
          this.$emit('onMergeRowOrColumn', { row, column, rowIndex, columnIndex });
        }
      },
      // 点击某一行时触发的函数
          // *** 按下左键然后移动鼠标到其它列放开左键,会有报错 -- 优化:添加点击行参数,
      rowClick(Row, Event, Column) {
        if (!Column || Column.type === 'selection' || Column.columnKey === 'operation' || Column.type === 'expand') {
          return
        }
        const data = {
          row: Row,
          event: Event,
          column: Column
        };
        this.$emit('onRowClick', data)
      },
      // 行类名的回调函数
      // 在表格数据中添加class字段即为表格行类名,配合css可对表格行中的自定义标签进行样式优化
      rowClassName(rowdata) {
        const data = this.table.data;
        let className = data[rowdata.rowIndex].class ? data[rowdata.rowIndex].class : '';
        if (className.length === 0) {
          return
        }
        className = className.join(' ');
        return className
      }
    }
  }
</script>

组件使用:

<tl-table :table="dataTable"></tl-table>

import tlTable from 'components/Table/index';

components: { tlTable }

data() {
   return {
       dataTable: {
            tr: []       // 表格行数据
            data: []   // 表格内容数据
       }
   }
}

此组件封装了element-ui中table组件的部分功能,列举如下(table数据参数为'table')

1、复选框功能 :table.hasSelect;默认为false,false为无,true为有,当为true时,通过监听自定义事件'onHandleSelectionChange'并传参来执行复选框更改选中项后的回调函数

2、表格折行功能:table.hasExpand;默认为false,false为无,true为有,当为true时,需要设置table.expands,里面是需要折行显示的数据

          expands: [
            {
              id: '1',
              label: '收款人姓名:',
              prop: 'gather_name'
            },
            {
              id: '2',
              label: '银行卡号:',
              prop: 'bank_card'
            },
            {
              id: '3',
              label: '户行:',
              prop: 'bank'
            }
          ]
3、按钮列功能:table.hasOperation;默认为false,false为无,true为有,当为true时,需要设置table.operation,里面是按钮属性数据
          operation: {             // 操作功能
            label: '操作',                // 操作列的行首文字
            width: '80',                // 操作列的宽度
            className: '',               // 操作列的class名
            data: [                      // 操作列数据
              {
                label: '删除',                // 按钮文字
                Fun: 'handleDelete',         // 点击按钮后触发的父组件事件
                size: 'mini',                // 按钮大小
                id: '1'                     // 按钮循环组件的key值
              }
            ]
          }

只需监听'handleDelete'事件即可执行按钮回调函数,label是按钮名称,size是element-ui中button组件控制按钮大小的属性

4、自定义列功能:table.tr[index].show;默认为true,show有三个值,true时,是普通表格列展示,false时,此列不展示,template时是自定义列。为template时,使用如下例:

    <tl-table :table="dataList" @onHandleSelectionChange="handleSelectionChange" @handleSync="handleSync" @handleoperate="handleoperate">
      <template slot-scope="props" slot="username">
        <a class="template-username" :href="'/#/bombscreen?mobile=' + props.obj.row.id" target="_blank">{{ props.obj.row.username }}</a>
      </template>
    </tl-table>
    data() {
      return {
        dataTable: {
          tr: [
            {
              id: '1',
              label: '用户名',
              prop: 'username',
              show: 'template',
              className: 'username'
            },
            {
              id: '2',
              label: '真实姓名',
              prop: 'real_name'
            },
            {
              id: '3',
              label: '性别',
              prop: 'sex_value'
            },
            {
              id: '11',
              label: '客服',
              prop: 'agent_name'
            },
            {
              id: '7',
              label: '渠道',
              prop: 'channel_id'
            },
            {
              id: '8',
              label: '注册时间',
              prop: 'regist_time',
              minWidth: '150'
            },
            {
              id: '9',
              label: '上次登录时间',
              prop: 'login_time',
              minWidth: '150'
            },
            {
              id: '10',
              label: '用户状态',
              prop: 'status_value'
            }
          ],
          data: []
        }

 4、表位合计行:hasShowSummary:默认为false,false为无,true为有,当为true时,需要设置table.getSummaries属性,此属性值为函数,可传一个参数,参数为当前表格的列组成的数组,此属性最中return一个数组,即为合计行最终显示的数据,使用例子如下 
data() {
     return {
         dataTable: {
              tr: [],
              data: [],
              hasShowSummary: true,
              getSummaries() {
                   return ['合计', 'N/A', '2', '41']
              }
         }
     }
}

5、点击表格行事件:在父组件监听rowClick事件即可,此函数接受一个参数,包含三个属性,分别是:row:当前点击行数据,column:当前点击单元格所在列的列数据,event:原生事件对象。使用例子如下

<tl-table :table="dataTable" @onRowClick="rowClick"></tl-table>
      // 操作 —— 点击表格行
      rowClick(data) {
        const { column, row } = data;
        if (column.className === 'income') {
          if (row.online_type.toString() === '1') {
            this.$message({
              type: 'warning',
              message: '线下状态不可查看',
              duration: 2000
            });
            return
          }
          window.open(location.origin + '/#/daily/income?time=' + row.date + '&type=2');
          return
        }
        const form = this.dataDetailIncome.form;
        form.income = row.income;
        form.loan_money = row.loan_money;
        form.online_type = row.online_type.toString();
        form.statistic_date = row.date;
        form.id = row.id.toString();
        this.dataDetailIncome.disabledButton = row.online_type.toString() === '1' ? 'true' : 'false';
        this.dataDetailIncome.dialogFormVisible = true;
      }

6、自定义行类名,列类名:在table.tr中设置的className为列类名,在table.data中设置的class为行类名,行类名的class是一个数组,列类名的className是一个字符串,通过这两个类名,可实现表格中单独某些单元格样式或功能的调整,注意:行类名可在通过ajax获取表格数据成功后的回调函数中去赋值。

7、自定义列宽度,最小宽度:width,minWidth;直接写字符串形式的数字即可,不需要单位

8、加载动画:loading;默认为false,false时为无,true时为有

9、自定义表格边框:border;默认为false,false是为无,true时为有

10、合并单元格:hasMergeRowOrColumn;默认为false,false时为无,true时为有,当为true时,还需要监听自定义事件'onMergeRowOrColumn',此方法接受一个参数,包含四个属性row,column,rowIndex,columnIndex,此功能我还暂时未使用,所以至于具体如何使用,请移步element-ui官方文档自行查阅



  • 4
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 20
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 20
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值