vue + element ui table表格二次封装 常用功能

因为在做后台管理项目的时候用到了大量的表格, 且功能大多相同,因此封装了一些常用的功能, 方便多次复用。

组件封装代码:

<template>
  <el-table :data="tableData" size="medium"
            ref="multipleTable" border fit
            @sort-change="handleSort"
            @filter-change="filterHandler"
            @selection-change="handleSelectionChange">
    <!-- 多选框 -->
    <el-table-column
      type="selection"
      width="55">
    </el-table-column>
    <el-table-column v-for="(th, key) in tableHeader"
                     min-height="46"
                     :key="key"
                     :prop="th.prop"
                     :label="th.label"
                     :fixed="th.fixed"
                     :sortable="th.custom?'custom':false"
                     :filters="th.filters"
                     :column-key="th.columnKey"
                     :filtered-value="th.filteredValue"
                     :filter-multiple="th.filterMultiple"
                     :min-width="th.minWidth" align="center">
      <template slot-scope="scope">
        <!-- 操作按钮 -->
        <div v-if="th.operation">
          <el-button v-for="(o, key) in th.operation" :key="key"
                     @click="o.clickFun(scope.row)"
                     
                     type="text" size="mini">
            {{o.name}}
      </el-button>
        </div>
        <!-- 点击跳转页面 -->
        <div v-else-if="th.router">
          <router-link :to="{path: th.router.path, query: {expertFields: scope.row['fieldName']}}">{{scope.row[th.prop]}}</router-link>
        </div>
        <div v-else>
          <!-- 鼠标滑过显示气泡框 -->
          <el-popover v-if="th.describe"
                      popper-class="popover-el-class"
                      placement="bottom"
                      width="200"
                      trigger="hover"
                      :content="scope.row[th.prop]">
            <span class="describe-wrap" slot="reference" >{{ scope.row[th.prop] }}</span>
          </el-popover>
          <!-- 下拉选择框 -->
          <el-select v-else-if="th.selected" :disabled="!th.disabled" v-model="scope.row[th.prop]" @change="th.changeFunc" clearable>
            <el-option v-for="(item, index) in th.selected" :value="item.value" :label="item.text" :key="index"></el-option>
          </el-select>
          <!-- 纯展示数据 -->
          <span v-else-if="!th.formatData">{{ scope.row[th.prop] }}</span>
          <!-- 需要格式化的数据结构 -->
          <span v-else>{{ scope.row[th.prop] | formatters(th.formatData) }}</span>
        </div>
      </template>
    </el-table-column>
  </el-table>
</template>

<script>
  export default {
    name: 'comp-table',
    props: {
      tableData: {
        type: Array,
        default: function () {
          return []
        }
      },
      tableHeader: {
        type: Array,
        default: function () {
          return []
        }
      },
      multipleSelection: {
        type: Array,
        default: function () {
          return []
        }
      }
    },
  filters: {  
        formatters (val, format) {
          if (typeof (format) === 'function') {
            return format(val)
          } else return val
        }
  },
    methods: {
      handleSelectionChange (val) {
        this.$emit('update:multipleSelection', val)
      },
      handleSort (sort) {
        this.$emit('sort-events', sort)
      },
      filterHandler (filters) {
        this.$emit('filter-events', filters)
      }
    }
  }
</script> 

页面内调用:

<comp-table :tableData="tableData"
        :tableHeader="tableHeader"
        :multipleSelection.sync="multipleSelection"
        @filter-events="filterEvents"
        @sort-events="sortEvents">
</comp-table>

<script>
export default {
    data () {
        return {
             tableData: [], // 请求到的表格数据
             tableHeader: [ // 表头信息
             { prop: 'fieldName',
              label: '领域',
              filters: domainTypeData,
              columnKey: 'fieldType',
              filterMultiple: false,
              minWidth: '150px',
              fixed: true
            },
            { prop: 'fieidDetails', label: '详情', minWidth: '180px' },
            { prop: 'lawyerQuantity',
              label: '关联律师数量',
              minWidth: '150px',
              router: {path: '/'}
            },
            { prop: 'articlesNumber',
              label: '相关文章数量',
              router: {path: '/case-management'},
              minWidth: '150px'
            },
            { prop: 'operation',
              label: '相关服务',
              minWidth: '260px',
              style: {display: 'block'},
              operation: [
                {name: '服务方案一', clickFun: this.getServiceOne},
                {name: '服务方案二', clickFun: this.getServiceTwo},
                {name: '服务方案三', clickFun: this.getServiceThird}
              ]
            },
            { prop: 'gmtModified', custom: 'custom', label: '最后更新时间', minWidth: '180px', formatData: this.formatDate },
            { prop: 'updater', label: '最后更新人', minWidth: '120px' },
            { prop: 'operation',
              label: '操作',
              minWidth: '260px',
              operation: this.fieldStatus ? [
                {name: '上线', disabled: true, clickFun: this.onLineField},
                {name: '下线', underline: true, clickFun: this.underField}
              ] : [
                {name: '编辑', clickFun: this.editDomain},
                {name: '删除', clickFun: this.delField},
                {name: '待审核', clickFun: this.examineField}
              ]
            }
          ]   
        }
    }
}
</script>