Vue-cli+elementUI table table encapsulation

In the background system project written with elementUI and VUE, table components are often used. Here, a simple encapsulation, reuse and simplify the code of the table is carried out.
The general page is as follows:

Code directly~
Table Component Encapsulation, DataTable.vue

<template>
  <el-table
    ref="table"
    border
    v-bind="$props" 
    v-on="$listeners"
    >
    <el-table-column
      v-if="showSelection"
      type="selection"
      width="55"
      align="center"
    ></el-table-column>
    <el-table-column
      v-if="showIndex"
      label="Serial number"
      type="index"
      width="55"
      align="center"
      :index="indexMethod"
    ></el-table-column>
    <el-table-column
      v-for="column of computedColumns"
      :key="column.prop + column.label"
      :label="column.label"
      :prop="column.prop"
    >
      <template slot-scope="scope">
        <slot
          :name="getSlotName(column)"
          v-bind="{
            data: data,
            row: scope.row,
            $index: scope.$index,
            column
          }"
        >
          <render-content
            :option="{
              render: column.render,
              scope: scope,
              column: column
            }">
          </render-content>
        </slot>
      </template>
    </el-table-column>
  </el-table>
</template>
<script>
const RenderContent = {
  props: {
    option: Object
  },
  render (h) {
    if (this.option.render) {
      return this.option.render(h, this.option.scope)
    }
    const { row, $index } = this.option.scope
    const { column } = this.option
    const property = column.prop
    let value = row[property]
    if (column && column.formatter) {
      return <span>{column.formatter(row, column, value, $index)}</span>
    }
    if (column.type === 'index') {
      value = $index + 1
    }
    if (!value && value !== 0) {
      value = '-'
    }
    return <span>{value}</span>
  }
}
  export default {
    components: {
      RenderContent
    },
    props: {
      columns: {
        type: Array,
        default: () => []
      },
      data: {
        type: Array,
        default: () => []
      },
      showSelection: {
        type: Boolean,
        default: false
      },
      showIndex: {
        type: Boolean,
        default: false
      },
      indexMethod: {
        type: Function
      }
    },
    data() {
      return {
      }
    },
    computed: {
      computedColumns () {
        return this.columns.filter(column =>
          column.showIf ? column.showIf(this.data) : true
        )
      }
    },
    methods: {
      getSlotName (column) {
        if (typeof column.render === 'string') {
          return column.render
        }
        return `${column.prop}-column`
      }
    }
  }
  </script>

Use of components:

<template>
  <div>
    <div style="width: 800px;">
      <data-table
        :data="tableData"
        :columns="columns"
        showIndex
        showSelection
        @selection-change="handleSelectionChange"
      >
        <template slot="operate-column" slot-scope="scope">
          <el-button plain size="mini" type="primary" icon="el-icon-edit" @click="handleOperate(scope.row)"></el-button>
        </template>
      </data-table>
    </div>
  </div>
</template>
 <script>
 import DataTable from './DataTable.vue'
    export default {
      components: {
        DataTable
      },
      data() {
        return {
          columns: [
            {
              label: 'date',
              prop: 'date'
            },
            {
              label: 'Full name',
              prop: 'name'
            },
            {
              label: 'address',
              prop: 'address'
            },
            {
              label: 'activity',
              prop: 'activity',
              showIf: () => false
            },
            {
              label: 'operation',
              prop: 'operate'
            }
          ],
          tableData: [{
            date: '2016-05-02',
            name: '',
            address: '1518 lane, Jinsha River Road, Putuo District, Shanghai'
          }, {
            date: '2016-05-04',
            name: 'Xiao Hu Wang',
            address: '1517 lane of the market'
          }, {
            date: '2016-05-01',
            name: 'Xiao Hu Wang',
            address: '1519 lane of the market'
          }, {
            date: '2016-05-03',
            name: 'Xiao Hu Wang',
            address: '1516 lane of the market'
          }]
        }
      },
      methods: {
        handleSelectionChange (val) {
          // Checklist
          console.log(val)
        },
        handleOperate (row) {
          // row operate
          console.log(row)
        }
      }
    }
  </script>

It's easy to encapsulate, but it should also be used in many occasions. Then take time to supplement other functions, such as table cell style, inline table and so on.~~~

Tags: Vue

Posted on Tue, 08 Oct 2019 00:22:01 -0700 by dmschenk