- json数组生成table列
- 表格数据本地分页
- 列支持动态显示/隐藏,列顺序支持自定义
- 编辑行,根据行数据动态生成form
- form支持自定义校验
<template>
<div>
<div id="box">
<el-table :data="tableData.slice((page.currentPage - 1) * page.pageSize, page.currentPage * page.pageSize)" ref="table" style="width: 100%" border height="400">
<el-table-column v-for="item in headList" align="center" show-overflow-tooltip width="100px" :prop="item.prop" :key="item.prop+Math.random()" :label="item.label"></el-table-column>
<el-table-column fixed="right" align="center">
<template slot="header" >
<el-button type="primary" size="small" icon="el-icon-s-tools" circle @click="delHeader"></el-button>
</template>
<template slot-scope="scope">
<span class="editrow" @click="editrow(scope.row)">编辑</span>
</template>
</el-table-column>
</el-table>
<div class="block" style="text-align:right;margin-top:10px">
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="page.currentPage"
:page-sizes="page.sizesArray"
:page-size="page.pageSize"
layout="total, prev, pager, next, jumper, sizes"
:total="page.total">
</el-pagination>
</div>
</div>
<el-dialog title="编辑" :visible.sync="dialogVisible" width="600px" >
<div style="height:400px;overflow:auto;">
<el-form :model="addOrUpdateForm" ref="addOrUpdateForm" label-width="100px" class="demo-dynamic" :rules="rules">
<el-form-item v-for="(item, index) in headList" :label="item.label" :key="index" :prop="item.prop">
<el-input v-model="addOrUpdateForm[item.prop]" ></el-input>
</el-form-item>
</el-form>
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false">取 消</el-button>
<el-button type="primary" @click="submitForm('addOrUpdateForm')">确 定</el-button>
</span>
</el-dialog>
<el-dialog title="列操作" :visible.sync="colOprationVisible" width="600px" >
<div style="height:400px;overflow:auto;">
<el-table :data="formList" style="width: 100%" border height="400">
<el-table-column align="center" width="100px" prop="prop" label="列名"></el-table-column>
<el-table-column label="是否启用">
<template slot-scope="scope">
<el-switch v-model="scope.row.show" :active-value="1" :inactive-value="2" active-color="#409eff" inactive-color="#B9B9B9"
@change="changeSwitch(scope.row)"/>
</template>
</el-table-column>
<el-table-column label="是否必填">
<template slot-scope="scope">
<el-switch v-model="scope.row.required" :active-value="1" :inactive-value="2" active-color="#409eff" inactive-color="#B9B9B9"
@change="changeSwitch(scope.row)"/>
</template>
</el-table-column>
<el-table-column align="center" width="100px" prop="sort" label="排序"></el-table-column>
<el-table-column label="操作" fixed="right" align="center" width="150px">
<template slot-scope="scope">
<span v-if="scope.row.sort!=0" class="editrow" @click="up(scope.row)" style="margin-right:10px">上升</span>
<span v-if="scope.row.sort!=formList.length-1" class="editrow" style="margin-right:10px" @click="down(scope.row)">下降</span>
<span v-if="scope.row.sort!=0" class="editrow" @click="upToZero(scope.row)" style="margin-right:10px">置顶</span>
</template>
</el-table-column>
</el-table>
</div>
<span slot="footer" class="dialog-footer">
<el-button type="primary" @click="colOprationVisible = false">关 闭</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
export default {
data() {
return {
page:{
currentPage: 1, //当前第几页
sizesArray: [10,20,30,50],//下拉每页条数
pageSize: 10, //每页条数
total: 66 //总条数
},
colOprationVisible: false,
dialogVisible: false,
//列数
collen: 2,
//原始列头
formList: [],
//展示的列头
headList: [],
//表格内容
tableData: [],
//校验规则
rules: {},
//编辑行数据
addOrUpdateForm: {},
};
},
mounted(){
for(let i=0;i<this.collen;i++){
this.formList.push({
id: i,
sort: i,
required: 1,
show: 1,
prop: "column"+i,
label: "column"+i
})
};
this.delHeadData();
for(let i=0;i<this.page.total;i++){
this.tableData[i] = {id: i};
for(let j=0;j<this.formList.length;j++){
this.tableData[i][this.formList[j].prop] = i+"_"+j
}
}
},
methods: {
editrow(row) {
this.rules = {};
this.headList.map(x=>{
this.rules[x.prop] = []
if(x.required==1){
this.rules[x.prop].push({required: true,message: '请输入'+x.label,trigger: 'blur'})
}
if(x.prop=="column1"){
this.rules[x.prop].push({validator: this.checkNumber,trigger: 'blur'})
}
});
this.addOrUpdateForm = Object.assign({},row)
this.dialogVisible = true;
},
checkNumber(rule, value, callback){
if (!/^[1-9]\d*$/.test(value)) {
callback(new Error('请输入数字'));
} else {
callback();
}
},
submitForm(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
alert("submit!");
} else {
console.log("error submit!!");
return false;
}
});
},
resetForm(formName) {
this.$refs[formName].resetFields();
},
handleSizeChange(val) {
this.page.pageSize = Number(val);
},
handleCurrentChange(val) {
this.page.currentPage = Number(val);
},
changeSwitch(){
this.delHeadData();
},
delHeader(){
this.colOprationVisible = true;
},
up(row){
let curr = row.sort;
let next = this.formList[curr-1];
row.sort = curr-1;
this.formList[curr-1] = row;
next.sort = curr;
this.formList[curr] = next;
this.delHeadData()
},
down(row){
let curr = row.sort;
let next = this.formList[curr+1];
row.sort = curr+1;
this.formList[curr+1] = row;
next.sort = curr;
this.formList[curr] = next;
this.delHeadData()
},
upToZero(row){
delete this.formList[row.sort];
this.formList = this.formList.filter(x=>{
return x
});
this.formList.unshift(row);
this.formList.map((x,i)=>{
x.sort = i;
});
this.delHeadData()
},
delHeadData(){
this.headList = [];
this.formList.map(x=>{
if(x.show==1){
this.headList.push(x);
}
})
this.headList = Object.assign([],this.headList)
this.$nextTick(() => {
this.$refs.table.doLayout();
})
}
},
};
</script>
<style scoped>
#box{
padding: 20px;
}
.demo-dynamic {
width: 500px;
padding: 20px;
}
.editrow {
color: #409eff;
cursor: pointer;
}
.el-pager li.active {
color: #409eff;
cursor: default;
}
.el-button--primary {
color: #fff;
background-color: #409eff;
border-color: #409eff;
}
.el-table__fixed::before, .el-table__fixed-right::before{
height: 0px;
}
</style>