天天看點

vue element table二次封裝更新版

 之前封裝的是簡單的table 但是因為項目需要,需要為table加上多選或行展開功能,就進行了修改

i-table.vue

<template>
  <el-table
    ref="table"
    :data="data"
    :show-header="showHeader"
    :
    :max-height="maxHeight"
    :v-loading="loading"
    :class="className"
    :row-key="rowKey"
    :expand-row-keys="expands"
    highlight-current-row
    @sort-change="handleSortChange"
    @selection-change="handleSelectionChange"
    @expand-change="expendDetail"
  >
    <!-- 展開行 -->
    <el-table-column v-if="expand" type="expand" width="40">
      <template slot-scope="scope">
        <el-form label-position="left" inline class="demo-table-expand" label-width="80px">
          <el-form-item
            v-for="(item,index) in detilOptions"
            :label="item.label + ': '"
            :key="index"
          >
            <span v-if="!item.html&&!item.formatter">{{scope.row[item.prop]}}</span>
            <span v-if="!item.html && item.formatter">{{item.formatter(scope.row[item.prop])}}</span>
            <span v-html="scope.row[item.prop]" v-if="item.html"></span>
          </el-form-item>
        </el-form>
      </template>
    </el-table-column>
    <!-- 多選 -->
    <el-table-column v-if="selection && !radioShow" type="selection" width="55"></el-table-column>
    <!-- 單選 -->
    <el-table-column v-if="radioShow && !selection">
      <template slot-scope="scope">
        <el-radio
          class="radio"
          v-model="selectedRadio"
          :label="scope.row[radioLabel]"
          @change.native="getCurrentRow(scope.row)"
        >&nbsp;</el-radio>
      </template>
    </el-table-column>
    <!-- 序号 -->
    <el-table-column v-if="indexOrNot" label="序号" type="index" :index="indexMethod" width="60"></el-table-column>
    <template v-for="colConfig in colConfigs">
      <slot v-if="colConfig.slot" :name="colConfig.slot"></slot>
      <component v-else-if="colConfig.component" :is="config.component" :col-config="colConfig"></component>
      <el-table-column v-else v-bind="colConfig"></el-table-column>
    </template>
  </el-table>
</template>

<script>
export default {
  props: {
    colConfigs: {
      type: Array,
      default: function () {
        return []
      }
    },
    data: {
      type: Array,
      default: function () {
        return []
      }
    },
    showHeader: {
      type: Boolean,
      default: true
    },
    border: {
      type: Boolean,
      default: false
    },
    maxHeight: {
      type: [String, Number],
      default: null
    },
    loading: {
      type: Boolean,
      default: false
    },
    className: {
      type: String,
      default: ''
    },
    rowKey: {
      type: String,
      default: ''
    },
    selection: {
      type: Boolean,
      default: false
    },
    radioShow: {
      type: Boolean,
      default: false
    },
    radioLabel: {
      type: String,
      default: 'id'
    },
    expand: {
      type: Boolean,
      default: false
    },
    uniqueOpened: {
      type: Boolean,
      default: true
    },
    detilOptions: [Array],
    indexOrNot: [Boolean],
    currentPage: {
      type: Number,
      default: 1
    },
    pageSize: {
      type: Number,
      default: 10
    }
  },
  data() {
    return {
      selectedRadio: '',
      expands: []
    }
  },
  components: {},
  computed: {},
  watch: {},
  created() {},
  methods: {
    indexMethod(index) {
      return index + 1 + (this.currentPage - 1) * this.pageSize
    },
    handleSelectionChange(val) {
      this.$emit('handleSelectionChange', val)
    },
    getCurrentRow(row) {
      this.$emit('radioChange', row)
    },
    expendDetail(row, expandedRows) {
      // 是否隻展開一行
      if (this.uniqueOpened) {
        if (expandedRows.length > 1) {
          this.data.forEach(item => {
            if (item.id !== row.id) {
              this.$refs['table'].toggleRowExpansion(item, false)
            }
          })
        }
      }
      this.$emit('detailClick', row)
    },
    handleSortChange(column) {
      this.$emit('handleSortChange', column)
    }
  }
}
</script>

<style>
.demo-table-expand .el-form-item {
  margin-right: 0;
  margin-bottom: 0;
  width: 50%;
}
</style>
           

在元件中使用

import iTable from '@/components/table/i-table'
           
components: { iTable },
           

使用

<i-table
        :data="userList"
        class="table"
        :col-configs="colConfigs"
        row-key="id"
        radioShow
        expand
        :detilOptions="detilOptions"
        radioLable="id"
        @handleSortChange="handleSortChange"
        @radioChange="radioChange"
      >
        <el-table-column slot="operate" label="操作">
          <template slot-scope="scope">
            <el-button type="text" size="small" @click="edit(scope.row)">編輯</el-button>
            <el-button type="text" size="small" @click="deleteUser(scope.row)">删除</el-button> 
          </template>
        </el-table-column>
      </i-table>
           

配置項

colConfigs: [
        {
          prop: 'name',
          label: '姓名'
        },
        {
          prop: 'sex',
          label: '性别',
          formatter: val => {
            //這裡的val是row Object
            return this.sexFormat(val.sex)
          }
        },
        { prop: 'birth', label: '出生日期', sortable: true },
        { prop: 'age', label: '年齡' },
        { prop: 'addr', label: '位址' },
        { slot: 'operate' }
      ],
      detilOptions: [
        {
          prop: 'name',
          label: '姓名'
        },
        {
          prop: 'sex',
          label: '性别',
          formatter: val => {
            return this.sexFormat(val)
          }
        },
        { prop: 'birth', label: '出生日期' },
        { prop: 'age', label: '年齡' },
        { prop: 'addr', label: '位址' }
      ],
           

methods 

sexFormat(val) {
      return val === 0 ? '男' : '女'
    },
    radioChange(val) {
      console.log(val)
    },
    handleSortChange(val) {
      console.log(val)
    },
           
vue