1、table 组件以及弹窗组件
<!--表格组件 -->
<template>
<section class="ces-table-page">
<!-- 表格操作按钮 -->
<section class="ces-handle" v-if='isHandle'>
<el-button
v-for='(item,index) in tableHandles'
:key="index"
: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%"
:cell-style="{textAlign: 'center'}"
:header-cell-style="{textAlign: 'center', color: '#333', background: '#F5F7FA'}"
:border='isBorder'
@select='select'
@select-all='selectAll'
@row-click="handleRowClick"
:defaultSelections="defaultSelections"
v-loading='loading'
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, index) in item.btnList"
:key="index"
v-if="!btn.isShow || (btn.isShow && btn.isShow(scope.$index, scope.row))"
:disabled="btn.isDisabled && btn.isDisabled(scope.$index, 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,index) in item.radios" :key="index" :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,index) in item.checkboxs" :key="index" :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-sizes="[5, 10, 15, 20]"
: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:5,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)
},
// 点击行选中
handleRowClick(row, col, event) {
this.$emit('select',row)
this.$refs.cesTable.toggleRowSelection(row)
},
//
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-handle {
margin-bottom: 10px;
}
.ces-pagination {
margin-top: 18px;
}
.ces-table-require::before{
content:'*';
color:red;
}
</style>
3、弹窗组件
<template>
<div class="dialog-container">
<el-dialog
:title="dialogDatas.title"
:width="dialogDatas.width"
:visible.sync="visible"
@close="$emit('updateShow', false)"
:show="show">
<!-- <span>this is a dialog.</span> -->
<slot></slot>
<span slot="footer" class="dialog-footer">
<el-button @click="visible = false">取 消</el-button>
<el-button type="primary" @click="visible = false">确 定</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
export default {
data () {
return {
visible: this.show
};
},
props: {
show: {
type: Boolean,
default: false
},
dialogDatas: {
type: Object,
required: true
}
},
watch: {
show () {
this.visible = this.show;
}
}
};
</script>
2、在组件中调用
<template>
<div>
<xy-table
size='mini'
:isSelection='true'
:isIndex='true'
:isPagination='true'
:isHandle='true'
:tableData='tableData'
:tableCols='tableCols'
:tableHandles='tableHandles'
:pagination='pagination'
@refresh="refresh"
@select="select"
>
</xy-table>
<!-- 弹窗 -->
<xy-modal :show.sync="show" :dialogDatas="dialogDatas" @updateShow="dialogShow">
<xy-edit ref='xyEdit' :that='that'
:editCfg='editForm'
:editData='editData'
:editRules='editRules' >
</xy-edit>
</xy-modal>
</div>
</template>
<script>
import xyTable from '@/components/common/Table/xyTable'
import xyModal from '@/components/common/Modal/xyModal'
import xyEdit from '@/components/common/Form/addOrEditForm'
let sexs=[{label:'男',value:'M'},{label:'女',value:'F'}]
let sexProps={label:'label',value:'value'}
let intersts=[{label:'羽毛球',value:'badminton'},{label:'篮球',value:'basketball'},{label:'足球',value:'football'},{label:'兵乓球',value:'pong'}]
let interstProps={label:'label',value:'value'}
export default {
components: {
xyTable,
xyModal,
xyEdit
},
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 {
show: false,
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:[
{isShow: (index,row) => this.showEdit(index,row),isDisabled: (index,row) => this.disabledBtn(index,row), type:'primary',label:'编辑',handle:row=>this.edit(row)},
{type:'danger',label:'删除',handle:row=>''}
]}
],
tableHandles:[
{label:'新增',type:'primary',handle:row=>this.addDatas()}
],
pagination:{
pageSize:5,
pageNum:1,
total:7
},
dialogDatas: {
title: '新增', // 新增或编辑
width: '500px' // dialog 宽度
},
that: this,
editForm: [
{label: '姓名', prop: 'name', type: 'input', width: '280px', change: data=> console.log(data)},
{label: '年龄', prop: 'age', type: 'input', width: '280px'},
{label: '性别', prop: 'sex', type: 'radio', radios: sexs, width: '280px'},
{label: '爱好', prop: 'interst', type: 'checkbox', checkboxs: intersts, width: '280px'},
],
// 编辑表单的数据
editData: {
name: null,
age: null,
sex: null,
interst: []
},
// 表单验证
editRules: {
name: [{requied: true, message: '请输入姓名', trigger: 'blur'}]
}
}
},
methods: {
showEdit(index,row) {
return true
},
disabledBtn(index,row) {
if (index == 0) {
return true
}
},
dialogShow() {
this.show = false
},
addDatas() {
this.show = true
this.dialogDatas.title = '新增'
for (let k of Object.keys(this.editData)) {
if (k == 'interst') {
this.editData[k] = []
} else {
this.editData[k] = null
}
}
console.log(this.editData)
},
edit(row) {
this.show = true
let editRow = JSON.parse(JSON.stringify(row))
this.dialogDatas.title = '编辑'
if (editRow.sex == '女') {
editRow.sex = "F"
} else {
editRow.sex = "M"
}
console.log(editRow)
let interstArr = intersts.filter(function(product){
return product.label === editRow.interst
})
editRow.interst = [interstArr[0].value]
this.editData = editRow
},
refresh() {
console.log('翻页')
},
select(rows, row) {
console.log(rows, row)
}
}
}
</script>