基于element-ui封装table组件

 基于element-ui实现的封装table,表格列通过render函数使用jsx渲染处理单个字段

效果如下

表格组件代码

<template>
  <div class="table-management">
    <el-table style="width: 100%"
              :data="tblData"
              v-loading="tbLoading"
              v-bind="attrs"
              element-loading-text="正在加载"
              @selection-change="handleSelectionChange">
      <el-table-column v-if="isSelect"
                       type="selection"
                       width="40">
      </el-table-column>
      <el-table-column v-for="(item, index) in column"
                       :key="index"
                       :type="item.type"
                       :index="item.index"
                       :column-key="item.columnKey"
                       :label="item.label"
                       :prop="item.prop"
                       :width="item.width"
                       :min-width="item.minWidth"
                       :fixed="item.fixed"
                       :header-align="item.headerAlign"
                       :align="item.align"
                       :show-overflow-tooltip="showOverflowTooltip">
        <template slot="header">
          <div v-if="item.tip">
            <span>{{item.label}}</span>
            <el-tooltip placement="right">
              <div slot="content">
                <div v-for="(items,index) in item.tipData"
                     :key="index">
                  <p>
                    {{items.msg}}
                  </p>
                </div>
              </div>
              <i class="el-icon-question"></i>
            </el-tooltip>
          </div>
          <p v-else>{{item.label}}</p>
        </template>
        <template slot-scope="scope">
          <expand-dom v-if="item.render"
                      :render="item.render"
                      :row="scope.row"
                      :index="scope.$index"
                      :column="item"></expand-dom>
          <span v-else>{{ scope.row[item.prop]||'-' }}</span>
        </template>
      </el-table-column>
    </el-table>
    <div class="pagination">
      <el-pagination @size-change="handleSizeChange"
                     @current-change="handleCurrentChange"
                     :current-page="pagination.curPage"
                     :page-sizes="pagination.pageSizes||defaultPagination.pageSizes"
                     :page-size="pagination.pageSize"
                     :layout="pagination.layout||defaultPagination.layout"
                     :total="pagination.total"
                     v-bind="pagination.attrs">
        <span class="el-pagination__total">{{totalText}}</span>
      </el-pagination>
    </div>
  </div>
</template>
<script>
export default {
  props: {
    tblData: { type: Array }, // 表格数据list
    column: { type: Array }, // 表格展示的表头以及单元格字段
    isSelect: { type: Boolean, default: false }, // 是否显示选中组件
    tbLoading: { type: Boolean, default: false }, // 表格加载loading
    pagination: {
      type: Object,
      require: true
    },
    // 表格的其他属性
    attrs: Object
  },
  components: {
    expandDom: {
      functional: true,
      props: {
        row: Object,
        render: Function,
        index: Number,
        column: {
          type: Object,
          default: null
        }
      },
      render: (h, ctx) => {
        const params = {
          row: ctx.props.row,
          index: ctx.props.index
        }
        if (ctx.props.column) params.column = ctx.props.column
        return ctx.props.render(h, params)
      }
    }
  },
  data () {
    return {
      showOverflowTooltip: true,
      defaultPagination: {
        pageSizes: [10, 20, 50, 100],
        layout: 'slot, prev, pager, next,sizes'
      }
    }
  },
  computed: {
    totalText () {
      const { total, curPage, pageSize } = this.pagination
      const range = [total === 0 ? 0 : (curPage - 1) * pageSize + 1, curPage * pageSize > total ? total : curPage * pageSize]
      return `共${total}条,当前页为  ${range[0]} - ${range[1]}  页`
    }
  },
  methods: {
    // 选中方法回调
    handleSelectionChange (val) {
      // 选中事件
      this.$emit('handleSelectBtn', val)
    },
    handleButton (methods, row, index) {
      // 按钮事件
      this.$emit('handleButton', { methods: methods, row: row, index: index })
    },
    // 分页api(展示每页显示条数)
    handleSizeChange (val) {
      this.$emit('handleSizeChange', val)
    },
    // 分页点击api(获取当前页数据)
    handleCurrentChange (val) {
      this.$emit('handleCurrentChange', val)
    }
  },
  mounted () { }
}
</script>
<style lang="scss" scope>
.table-management {
  .pagination {
    display: flex;
    justify-content: flex-end;
    margin: 10px 0;
  }
}
.table-management .el-table-column--selection .cell {
  text-overflow: unset;
}
.table-management {
  .el-pagination.is-background .btn-next,
  .el-pagination.is-background .btn-prev,
  .el-pagination.is-background .el-pager li {
    background: white;
  }
  .el-pagination.is-background .el-pager li:not(.disabled).active {
    border: 1px solid #409eff;
    color: #409eff;
    background: white;
  }
}
</style>

使用组件

<template>
  <div>
    <table-tem @handleSizeChange="handleSizeChange"
               @handleCurrentChange="handleCurrentChange"
               :tblData="tblData"
               :attrs="attrs"
               :column="column"
               :isSelect="true"
               :pagination="pagination"
               @handleSelectBtn="handleSelectBtn">
    </table-tem>
  </div>
</template>
<script>
// 引入组件table
import tableTem from './table-it.vue'
export default {
  components: {
    tableTem
  },
  data () {
    return {
      attrs: {
        border: true
        // fit:false
      },
      tblData: [
        {
          imgUrl: 'https://img.yzcdn.cn/public_files/2017/10/24/2f9a36046449dafb8608e99990b3c205.jpeg',
          timeList: [
            { startTime: '2022-1-2', endTime: '2020-4-3' }
          ],
          type: 1,
          StatusDesc: 'ssss',
          createTime: '2020-3-4'
        },
        {
          imgUrl: 'https://img.yzcdn.cn/public_files/2017/10/24/320454216bbe9e25c7651e1fa51b31fd.jpeg',
          timeList: [
            { startTime: '2022-1-2', endTime: '2020-4-3' }
          ],
          type: 2,
          StatusDesc: 'ssss',
          createTime: '2020-3-4'
        }
      ], // 表格展示数据list,由接口获取
      pagination: {
        total: 67,
        pageSize: 10,
        curPage: 1,
        attrs: {
          // hideOnSinglePage: true,
          background: true
        }
      },
      selectList: [], // 储存列表选中的数据
      column: [// 表格展示列,也就是表头字段
        {
          prop: 'imgUrl', // 表格渲染字段
          label: 'logo', // 表头显示名字
          headerAlign: 'center', // 表头样式-居中显示
          align: 'center', // 单元格样式-居中显示
          width: 120,
          // 当前渲染字段api--列出显示img的api
          render: (h, { row }) => <img src={row.imgUrl} width='80' height='80'></img>
        },
        {
          prop: 'timeList',
          label: '时间段',
          headerAlign: 'center',
          align: 'center',
          render: this.renderTimeList
        },
        {
          prop: 'type',
          label: '类型',
          headerAlign: 'center',
          align: 'center',
          render: this.renderType
        },
        {
          prop: 'StatusDesc',
          label: '状态',
          headerAlign: 'center',
          align: 'center',
          tip: true, // 是否展示表头状态描述提示信息
          tipData: [// 展示的提示信息数组
            { msg: '我是展示在状态表头里面的提示信息1' },
            { msg: '我是展示在状态表头里面的提示信息2' }
          ],
          minWidth: 110
        },
        {
          prop: 'createTime',
          label: '创建时间',
          headerAlign: 'center',
          align: 'center',
          minWidth: '90'
          // render: this.renderCreateTime// 当前渲染字段api--(后端返回的是时间戳需要前端处理一下)
        },
        // 接下来就着重说一下表格的操作按钮(相同的字段前面都表述清楚了)
        {
          prop: 'operation',
          label: '操作',
          headerAlign: 'center',
          align: 'center',
          minWidth: '110',
          // 该方法是针对操作一列的按钮的api
          render: (h, { row }) => {
            return <div>
              <el-button type='danger' icon='el-icon-edit' style="cursor:pointer;" onClick={this.btnClick}>修改</el-button>
              <el-button type='primary' style="cursor:pointer;" onClick={() => this.btnClick(row)}>删除</el-button>
            </div>
          }
        }
      ]
    }
  },
  methods: {
    // 分页点击
    handleCurrentChange (val) {
      this.pagination.curPage = val
      // 掉接口:获取表格数据接口
    },
    // 获取每页显示条数
    handleSizeChange (val) {
      this.pagination.curPage = 1
      this.pagination.pageSize = val
      // 掉接口:获取表格数据接口
    },
    // 列表选中回调api
    handleSelectBtn (val) {
      this.selectList = val
    },
    // 渲染时间数组
    renderTimeList (h, { row: { timeList } }) {
      const timeListArr = []
      for (const i of timeList) {
        timeListArr.push(i.startTime + '~' + i.endTime)
      }
      return <div>
        {timeListArr.map((item, index) => <div>{item}</div>)}
      </div>
    },
    // 状态渲染类
    renderType (h, { row }) {
      let statusStr = ''
      if (row.type === 1) {
        statusStr = '类型1'
      } else if (row.type === 2) {
        statusStr = '类型2'
      } else if (row.type === 3) {
        statusStr = '类型3'
      } else {
        statusStr = ''
      }
      return <span>{statusStr}</span>
    },
    // 下面是操作按钮一列
    // 操作
    btnClick (row) { console.log(row) }
  }
}

</script>

实现中借鉴博主文章:elementui提取table表格封装组件,elementui提取table表格单列展示按钮的展示效果_管火火火的博客-CSDN博客_elementui table 封装

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值