zoukankan      html  css  js  c++  java
  • 使用element-ui二次封装一个可复用表格组件

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

    源码链接:表格组件

    组件源码:Table.vue

    <!--表格组件 -->
    <template>
    <section class="ces-table-page">
      <!-- 表格操作按钮 -->
        <section class="ces-handle" v-if='isHandle'>
          <el-button v-for='item in tableHandles' :size="item.size || size" :type="item.type" :icon='item.icon' @click="item.handle()">{{item.label}}</el-button>
        </section>
        <!-- 数据表格 -->
        <section class="ces-table">
            <el-table  :data='tableData' :size='size' height="100%" 
              :border  ='isBorder'
              @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="indexLabel" align="center" width="50"></el-table-column>
                <!-- 数据栏 -->
                <el-table-column v-for="item in tableCols" 
                  :key="item.id"
                  :prop="item.prop" 
                  :label="item.label" 
                  :width="item.width"
                  :align="item.align" 
                  :render-header="item.require?renderHeader:null"
                  >
                    <template slot-scope="scope" >
                      <!-- html -->
                      <span v-if="item.type==='Html'" v-html="item.html(scope.row)"></span>
                      <!-- 按钮 -->
                      <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 || size" 
                          :icon="btn.icon" 
                          @click="btn.handle(scope.row)">{{btn.label}}</el-button>
                        </span>
                      <!-- 输入框 -->
                      <el-input v-if="item.type==='Input'" v-model="scope.row[item.prop]" :size="size" 
                        :disabled="btn.isDisabled && btn.isDisabled(scope.row)"
                        @focus="item.focus && item.focus(scope.row)"></el-input>
                      <!-- 下拉框 -->
                      <el-select v-if="item.type==='Select'" v-model="scope.row[item.prop]" :size="size" :props="item.props"
                        :disabled="btn.isDisabled && btn.isDisabled(scope.row)" 
                        @change='item.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]"
                        :disabled="btn.isDisabled && btn.isDisabled(scope.row)"
                        @change='item.change && item.change(scope.row)'>
                          <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]" 
                        :disabled="btn.isDisabled && btn.isDisabled(scope.row)"
                        @change='item.change && item.change(scope.row)'>
                          <el-checkbox v-for="ra in item.checkboxs" :label="ra.value">{{ra.label}}</el-checkbox>
                      </el-checkbox-group>
                      <!-- 评价 -->
                      <el-rate v-if="item.type==='Rate'" v-model="scope.row[item.prop]"
                        :disabled="btn.isDisabled && btn.isDisabled(scope.row)"
                        @change='item.change && item.change(scope.row)'></el-rate>
                      <!-- 开关 -->
                      <el-switch v-if="item.type==='Switch'" v-model="scope.row[item.prop]"
                        :disabled="btn.isDisabled && btn.isDisabled(scope.row)"
                        @change='item.change && item.change(scope.row)'></el-switch>
                      <!-- 图像 -->
                      <img v-if="item.type==='Image'" :src="scope.row[item.prop]" @click="item.handle && item.handle(scope.row)"/>
                      <!-- 滑块 -->
                      <el-slider v-if="item.type==='Slider'" v-model="scope.row[item.prop]" 
                      :disabled="btn.isDisabled && btn.isDisabled(scope.row)"
                        @change='item.change && item.change(scope.row)'></el-slider>
                      <!-- 默认 -->
                      <span v-if="!item.type" 
                        :style="item.itemStyle && item.itemStyle(scope.row)" 
                        :class="item.itemClass && item.item.itemClass(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='isPagination'>
            <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="pagination.pageSize"
                :current-page="pagination.pageNum"
                :total="pagination.total"
            ></el-pagination>
        </section>
    </section>
    </template>
    
    <script>
    
    export default {
      props:{
        // 表格型号:mini,medium,small
        size:{type:String,default:'medium'},
        isBorder:{type:Boolean,default:true},
        loading:{type:Boolean,default:false},
        // 表格操作
        isHandle:{type:Boolean,default:false},
        tableHandles:{type:Array,default:()=>[]},
        // 表格数据
        tableData:{ type:Array,default:()=>[]},
        // 表格列配置
        tableCols:{ type:Array,default:()=>[]},
        // 是否显示表格复选框
        isSelection:{type:Boolean,default:false},
        defaultSelections:{ type:[Array,Object], default:()=>null},
        // 是否显示表格索引
        isIndex:{type:Boolean,default:false},
        indexLabel: {type:String,default:'序号'},
        // 是否显示分页
        isPagination:{type:Boolean,default:true},
        // 分页数据
        pagination:{ type:Object,default:()=>({pageSize:10,pageNum:1,total:0})},
        
      },
      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.pagination.pageNum = val;
          this.$emit('refresh');
        },
        handleSizeChange(val) {
          this.pagination.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>
    .ces-table-require::before{
      content:'*';
      color:red;
    }
    </style>
    View Code

    页面调用和搜索框组件同用

    <template>
      <div class="ces-main">
        <search-form 
          size='mini'
          labelWidth = '80px' 
          :searchData = "searchData"
          :searchForm = "searchForm"
          :searchHandle="searchHandle"></search-form>
        <ces-table 
          size='mini'
          :isSelection='true'
          :isIndex='true'
          :isPagination='true'
          :isHandle='true'
          :tableData='tableData' 
          :tableCols='tableCols' 
          :tableHandles='tableHandles'
          :pagination='pagination'
          >
          </ces-table>
      </div>
    </template>
    
    <script>
    import SearchForm from '@/components/common/Form/searchForm'
    import cesTable from '@/components/common/Table/Table'
    export default {
      data () {
    
        let sexs=[{label:'男',value:'M'},{label:'女',value:'F'}]
        let sexProps={label:'label',value:'value'}
        let intersts=[{label:'羽毛球',value:'badminton'},{label:'篮球',value:'basketball'}]
        let interstProps={label:'label',value:'value'}
        return {
    // 查询表单
          searchData:{
            name:null,
            age:null,
            sex:null,
            interst:null
          },
          searchForm:[
            {type:'Input',label:'姓名',prop:'name','180px',placeholder:'请输入姓名...'},
            {type:'Input',label:'年龄',prop:'age','180px',placeholder:'请输入年龄...'},
            {type:'Select',label:'性别',prop:'sex','180px',options:sexs,props:sexProps,change:row=>'',placeholder:'请选择性别...'},
            {type:'Checkbox',label:'爱好','180px',prop:'interst',checkboxs:intersts,props:interstProps}
          ],
          searchHandle:[
            {label:'查询',type:'primary',handle:()=>''},
            {label:'重置',type:'primary',handle:()=>''}
          ],
    
    // 表格
          tableData:[
            {name:'张三',age:'12',sex:'男',interst:'女'},
            {name:'筱华',age:'27',sex:'女',interst:'羽毛球'},
            {name:'张三',age:'12',sex:'男',interst:'女'},
            {name:'筱华',age:'27',sex:'女',interst:'羽毛球'},
            {name:'筱华',age:'27',sex:'女',interst:'羽毛球'},
            {name:'筱华',age:'27',sex:'女',interst:'羽毛球'},
            {name:'筱华',age:'27',sex:'女',interst:'羽毛球'}
            
          ],
          tableCols:[
            {label:'姓名',prop:'name'},
            {label:'年龄',prop:'age'},
            {label:'性别',prop:'sex'},
            {label:'爱好',prop:'interst'},
            {label:'操作',type:'Button',btnList:[
              {type:'primary',label:'编辑',handle:row=>''},
              {type:'danger',label:'删除',handle:row=>''}
            ]}
          ],
          tableHandles:[
            {label:'新增',type:'primary',handle:row=>''}
          ],
          pagination:{
            pageSize:10,
            pageNum:1,
            total:7
          }
        }
      },
      components:{
        cesTable,
        SearchForm
      }
    }
    </script>
    
    <style>
    
    </style>

    最终效果:

  • 相关阅读:
    路径查看linux 向内核注册总线例子
    属性应用Android Manifest之<provider>元素中文注释
    序数序列hdu 1394
    大分类分类Zen Cart大分类下直接显示产品列表插件
    虚拟化运行[OpenStack] VMWare产品介绍
    名称磁盘Linux系统监控的CPU、Mem、IO的OID
    端口服务器黑马韩前成linux从入门到精通proftpd服务器配置
    主库配置关于Dataguard Online redo log 和 Standby redo log
    尺寸品牌Jquery 仿淘宝京东多条件筛选 可自行结合ajax加载
    设置编辑(iPhone/iPad开发)设置UITextView为不可编辑状态
  • 原文地址:https://www.cnblogs.com/xingguozhiming/p/10673918.html
Copyright © 2011-2022 走看看