基于element-ui的el-table进行二次封装——通过配

2020-08-11  本文已影响0人  videring

麻烦点

改善点

用法示例

// test
<template>
  <div class="test">
      <config-table
              :columns="tableColumns"
              :loading="loading"
              :props="tableProps"
              @cell-click="handleCellClick"
              @row-click="handleCellClick"
              ref="cRef"
      >
          <div slot="append">测试slot append</div>
      </config-table>
      <el-button @click="toggle">更改选中状态</el-button>
  </div>
</template>

<script>
import configTable from './index'

export default {
  name: 'test',
  components: {
    configTable
  },
  data() {
    return {
      loading: false,
      tableProps: {
        'show-summary': true,
        'highlight-current-row': true,
        data: [
          {
            a: '123',
            b: '哈喽',
            c: '高层',
            d: 'm²',
            e: 234,
            f: 11.1,
            g: 12345
          },
          // {
          //   a: 'tyhj',
          //   b: '中国',
          //   c: '中层',
          //   d: 'kilo',
          //   e: 1111,
          //   f: 33.3,
          //   g: 456
          // }
        ]
      },
      tableColumns: [
        {
          type: 'selection',
          width: 100
        },
        {
          label: '项目编码',
          prop: 'a',
        }, {
          label: '项目名称',
          prop: 'b',
        }, {
          label: '项目特征',
          prop: 'c',
        }, {
          label: '单位',
          prop: 'd',
          minWidth: '200px',
          formatter: (row, column) => `单位:${row[column.property]}`,
          renderHeader: (h, d) => `我是${d.column.label}`, // 对应El-Table-column Attributes render-header
          // 优先级高于formatter,相当于el-table-column中作用域插槽
          renderCell: (h, props) => h('span', `${props.column.label}ing:${props.row[props.column.property]}`) // 这是自定义的El-Table-column Attributes,对应scopedSlot!!!
        }, {
          label: '基准模型',
          prop: '',
          render: null,
          data: null,
          children: [
            {
              label: '工程量',
              prop: 'e',
            }, {
              label: '综合单价',
              prop: 'f',
            }, {
              label: '综合合价',
              prop: 'g',
            }
          ]
        }
      ],
    }
  },
  methods: {
    handleCellClick(...args) {
      console.log(args)
    },
    toggle() {
      this.$refs.cRef.$refs.ref.toggleRowSelection(this.tableProps.data[0])
    },
  }
}
</script>

<style lang="scss" scoped>
  .test {
  }
</style>

效果图

源码

<script>
export default {
  name: 'config-table',
  props: {
    loading: {
      type: Boolean,
      default: () => false
    },
    props: { // 对应El-Table Attributes
      required: true,
      type: Object
    },
    columns: { // 对应El-Table-column Attributes
      required: true,
      type: Array,
      default: () => []
    },
  },
  render(createElement) {
    const render = (h, data) => {
      data = Array.isArray(data) ? data : [data]
      return data.map(col => {
        const { children } = col
        const props = {
          ...col
        }
        const hasChildren = Array.isArray(children) && children.length
        const hasCellRender = typeof col.renderCell === 'function'
        let cS = []
        if (hasChildren) {
          cS = render(h, children)
        }
        const colProps = {
          props
        }
        if (hasCellRender) {
          colProps.scopedSlots = {
            default(ps) {
              return col.renderCell(h, ps) // 通过renderCell,支持scopedSlots
            }
          }
        }
        return h('el-table-column', colProps, hasChildren ? cS : []) // 通过children属性,支持多级表头
      })
    }
    return createElement('el-table', {
      class: 'config-table',
      props: {
        ...this.props
      },
      on: {
        ...this.$listeners // 支持El-Table 原有所有Events
      },
      directives: [
        {
          name: 'loading',
          value: this.loading // 支持loading
        }
      ],
      ref: 'ref', // 通过这个ref,对应El-Table Methods
    }, render(createElement, this.columns).concat(createElement('template', { slot: 'append' },this.$slots.append))) // 支持El-Table slot append
  }
}
</script>

<style lang="scss" scoped>
  .config-table {
  }
</style>

上一篇 下一篇

猜你喜欢

热点阅读