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>
最终效果:

原文:https://www.cnblogs.com/xingguozhiming/p/10673918.html