使用element-ui二次封装一个可复用表格

element-ui表格封装的非常好,由于最近工作负责基础组件封装,封装更适合公司业务的复用组件,从表格开始:

表格组件代码:Table.vue

<!--表格组件 -->
<template>
<section class="ces-table-page">
  <!-- 表格 -->
    <section class="ces-table">
        <el-table 
          :data="tableData" 
          :size="size" 
          height="100%" 
          border  
          @select="select" 
          @select-all="selectAll" 
          v-loading="loading" 
          :defaultSelections='defaultSelections'
          ref='cesTable'>
            <el-table-column v-if="isSelection" type="selection" align="center" ></el-table-column>
            <el-table-column v-if="isIndex" type="index" label="序号" align="center" width="50"></el-table-column>
            <!-- 数据栏 -->
            <el-table-column v-if="isHtml" v-for="item in tableCols" :prop="item.prop" :label="item.label" >
              <span slot-scope="scope" v-html="item.html(scope.row)"></span>
            </el-table-column>
            <el-table-column v-for="item in tableCols" :key="item.id"  v-if="!isHtml"
                :prop="item.prop" 
                :label="item.label" 
                :width="item.width"
                :align="item.align" 
                :render-header="item.require?renderHeader:null"
                >
                  <template slot-scope="scope" >
                    <!-- 按钮 -->
                    <span v-if="item.type==='Button'" >
                      <el-button v-for="btn in item.btnList" 
                        v-if="!btn.isShow || (btn.isShow && btn.isShow(scope.row))"
                        :disabled="btn.isDisabled && btn.isDisabled(scope.row)"
                        :type="btn.type" 
                        :size="btn.size" 
                        :icon="btn.icon" 
                        @click="btn.handle(scope.row)">{{btn.label}}</el-button>
                      </span>
                    <el-button v-if="item.type==='TextButton'" type="text" size="mini" @click="item.handle(scope.row )">{{scope.row[item.prop]}}</el-button>
                    <!-- <el-button v-if="item.type==='DangerButton'" type="danger" @click="item.handle(scope.row )">{{scope.row[item.prop]}}</el-button> -->
                    <!-- 输入框 -->
                    <el-input v-if="item.type==='Input'" v-model="scope.row[item.prop]" size="mini" @focus="item.focus(scope.row)"></el-input>
                    <!-- 下拉框 -->
                    <el-select v-if="item.type==='Select'" v-model="scope.row[item.prop]" size="mini" :props="item.props" @change='item.change(scope.row)'>
                        <el-option v-for="op in item.options" :label="op[item.props.label]" :value="op[item.props.value]" :key="op[item.props.value]"></el-option>
                    </el-select>
                    <!-- 单选 -->
                    <el-radio-group v-if="item.type==='Radio'" v-model="scope.row[item.prop]">
                        <el-radio v-for="ra in item.radios" :label="ra.value">{{ra.label}}</el-radio>
                    </el-radio-group>
                    <!-- 复选框 -->
                    <el-checkbox-group v-if="item.type==='Checkbox'" v-model="scope.row[item.prop]">
                        <el-checkbox v-for="ra in item.checkboxs" :label="ra.value">{{ra.label}}</el-checkbox>
                    </el-checkbox-group>
                    <!-- 评价 -->
                    <el-rate v-if="item.type==='Rank'" v-model="scope.row[item.prop]"></el-rate>
                    <!-- 开关 -->
                    <el-switch v-if="item.type==='Switch'" v-model="scope.row[item.prop]"></el-switch>
                    <!-- 图像 -->
                    <img v-if="item.type==='Image'" :src="scope.row[item.prop]"/>
                    <!-- 滑块 -->
                    <el-slider v-if="item.type==='Slider'" v-model="scope.row[item.prop]"></el-slider>
                    <!-- 默认 -->
                    <span v-if="!item.type" :style="item.itemStyle && item.itemStyle(scope.row)">{{(item.formatter && item.formatter(scope.row)) || scope.row[item.prop]}}</span>
                  </template>
                </el-table-column>
        </el-table>
    </section>
    <!-- 分页 -->
    <section class="ces-pagination"  v-if='isPage'>
        <el-pagination style='display: flex;justify-content: center;height: 100%;align-items: center;'
            @current-change="handleCurrentChange"
            @size-change="handleSizeChange"
            layout="total,sizes ,prev, pager, next,jumper"
            :page-size="pageOrder.pageSize"
            :current-page="pageOrder.pageNum"
            :total="pageOrder.total"
        ></el-pagination>
    </section>
</section>
</template>

<script>

export default {
  props:{
    // 是否加载
    loading:{type:Boolean,default:false},
    // 默认选中
    defaultSelections:{
      type:[Array,Object],
      default:()=>null
    },
    // 表格数据
    tableData:{ type:Array,default:()=>[]},
    // 表格分页数据
    pageOrder:{ type:Object,default:function(){
      return {pageSize:10,pageNum:1,total:0}
    }
    },
    // 表格列
    tableCols:{ type:Array,default:()=> []},
    // 是否解析html字符串
    isHtml:{type:Boolean,default:false},
    // 是否显示表格复选框
    isSelection:{type:Boolean,default:false},
    // 是否显示表格索引
    isIndex:{type:Boolean,default:false},
    // 是否显示分页
    isPage:{type:Boolean,default:true},
    // 表格型号:mini,medium,small
    size:{type:String,default:'medium'},
    
  },
  data(){
    return {
    }
  },
  watch:{
    'defaultSelections'(val) {
        this.$nextTick(function(){
          if(Array.isArray(val)){
            val.forEach(row=>{
              this.$refs.cesTable.toggleRowSelection(row)
            })
          }else{
            this.$refs.cesTable.toggleRowSelection(val)
          }
        })
    }
  },
  methods:{
    select(rows,row){
      this.$emit('select',rows,row);
    },
    selectAll(rows){
      this.$emit('select',rows)
    },
    handleCurrentChange(val){
      this.pageOrder.pageNum = val;
      this.$emit('refresh');
    },
    handleSizeChange(val) {
      this.pageOrder.pageSize = val;
      this.$emit('refresh');
    },
    // tableRowClassName({rowIndex}) {
    //     if (rowIndex % 2 === 0) {
    //         return "stripe-row";
    //     }
    //     return "";
    // }
    renderHeader(h,obj) {
      return h('span',{class:'ces-table-require'},obj.column.label)
    },
  },
}
</script>
<style>
/* @import url("../../assets/css/Layout/main.css"); */
.ces-table-require::before{
  content:'*';
  color:red;
}
</style>

页面调用使用代码:index.vue

<template>
  <div class="ces-main">
    <Table 
        :that='that'
        :tableData="tableData"
        :tableCols="tableCfg"
        :pageOrder="pageOrder"
    ></Table>
  </div>
</template>

<script>

import Table from '@/components/common/Table/Table.vue'
import SearchForm from '@/components/common/Form/SearchForm'
export default {
  data () {
    return {
      that:this,
      tableCfg: [
        {label: '姓名', prop: 'name'},
        {label: '年龄', prop: 'age'},
        {label: '性别', prop: 'sex'},
        {label: '爱好', prop: 'interst'},
      ],
      tableData: [
        {name:'张三',age:'13',sex:'男',interst:'羽毛球'},
        {name:'筱华',age:'26',sex:'女',interst:'羽毛球'},
        {name:'华华',age:'13',sex:'女',interst:'羽毛球'}
      ],

      pageOrder: {
        pageSize: 10,
        total: 1,
        currentPage: 1
      }
    }
  },
  components:{
    Table,SearchForm
  }
}
</script>

<style>

</style>

最终效果:

猜你喜欢

转载自www.cnblogs.com/xingguozhiming/p/10673918.html