共计 6595 个字符,预计需要花费 17 分钟才能阅读完成。
需要
1. 表头数据不固定
2. 表头数据多层级
3. 表格跨行跨列
4. 表格可编辑
5. 编辑反对根本表单框
子组件代码
dynamic-header.vue
<template>
<div>
<el-form size="medium" class="horizontal" inline>
<slot name="search"></slot>
</el-form>
<div class="title" v-if="title">{{title}}</div>
<el-table
v-loading="listLoading"
:data="list"
:stripe="true"
class="flexible"
:border="true"
:span-method="arraySpanMethod"
style="overflow: auto"
:height="height"
ref="table"
width="100%"
>
<template
v-for="(item,index) in tableHeader">
<table-column v-if="item.children && item.children.length" :key="Math.random()" :coloumn-header="item"></table-column>
<el-table-column v-else class-name="custom"
:width="item.width?item.width:'auto'":fixed="item.fixed":key="Math.random()":label="item.tableHeadName"align="center">
<template slot-scope="scope">
<template v-if="item.isEdit">
<el-select
filterable
v-if='(item.htmlType =="select"|| item.htmlType =="radio") && item.dictData'
v-model.lazy="scope.row[item.tableFiled]">
<el-option
v-for="dict in item.dictData"
:key="dict[item.options.value] || dict.value"
:label="dict[item.options.label] || dict.label"
:value="parseInt(dict[item.options.value] || dict.value)"
/>
</el-select>
<el-date-picker
v-else-if='item.htmlType =="datetime"&& item.queryType !="BETWEEN"'clearable size="small"v-model.lazy="scope.row[item.tableFiled]"type="date"value-format="yyyy-MM-dd">
</el-date-picker>
<el-date-picker
v-else-if='item.htmlType =="datetime"&& item.queryType =="BETWEEN"'v-model.lazy="scope.row[item.tableFiled]"size="small"style="width: 240px"value-format="yyyy-MM-dd"type="daterange"range-separator="-"start-placeholder=" 开始日期 "end-placeholder=" 完结日期 "
></el-date-picker>
<el-input-number
v-else-if='item.htmlType =="number"'v-model.lazy="scope.row[item.tableFiled]"
clearable
size="small"
/>
<el-input
v-else
v-model.lazy="scope.row[item.tableFiled]"
clearable
size="small"
/>
</template>
<template v-else-if="item.template">
{{getTemplate(item.template,scope)}}
</template>
<template v-else>
<dict-tag v-if="item.dictData" :options="item.dictData" :value="scope.row[item.tableFiled]" />
<tempalte v-else-if="item.dictDataArray" >
<dict-tag v-for="(it,itIndex) in item.dictDataArray" v-if="scope.row[it.props] == it.value" :key="itIndex" :options="it.dictData" :value="scope.row[item.tableFiled]" />
</tempalte>
<template v-else>{{scope.row[item.tableFiled]}}</template>
</template>
</template>
</el-table-column>
</template>
<el-table-column v-if="pageParamInfo.oper" label="操作" :key="index" fixed="right" width="150">
<template slot-scope="scope">
<slot name="oper" :scope="scope.row"></slot>
</template>
</el-table-column>
</el-table>
<slot name="tableFooter" :scope="pageParamInfo.req"></slot>
</div>
</template>
<script>
import TableColumn from './table-column'
export default {
props: {
pageParamInfo: {
type: Object,
default(){return {}
}
},
tableHeader: {
type: Array,
default(){return []
}
},
RowRules: {
type: Array,
default(){return []
}
},
list: {
type: Object,
default(){return {}
}
},
title: {
type: String,
default: ""
},
listLoading: {
type: Boolean,
default: false
},
height: {
type: String,
default: "70vh"
},
},
// pageParamInfo 页面列表参数:url req 等等;// tableHeader 表头信息
components: {TableColumn,},
data() {return {}
},
watch: {tableHeight(val) {this.height = val}
},
created() {},
mounted() {},
methods: {getTemplate(template,scope){return eval(template)
},
arraySpanMethod({row, column, rowIndex, columnIndex}) {
let returnMap = {
rowspan: 1,
colspan: 1
}
const data = this.RowRules
if (data instanceof Array && data.length > 0) {
data.forEach(item => {if (item.col === (columnIndex + 1)) {if (rowIndex % item.row === 0) {
returnMap = {
rowspan: item.row,
colspan: 1
}
} else {
returnMap = {
rowspan: 0,
colspan: 0
}
}
}
})
}
return returnMap
},
// 列表
getList() {
this.listLoading = true
this.$http.post(this.pageParamInfo.url, this.pageParamInfo.req).then(res => {
this.listLoading = false
// this.list = res.data.list
})
},
// 文件上传中解决
handleExceed(event, file, fileList) {this.upload.isUploading = true},
// 文件上传胜利解决
handleSuccess(response, file, fileList) {
this.upload.open = false
this.upload.isUploading = false
this.$refs.upload.clearFiles()
this.$alert(response.message, '导入后果', {dangerouslyUseHTMLString: true,})
this.getList()},
// 重置
reset() {
/* this.listLoading = true
this.$http.post('busprojecttask/findTaskList', this.req).then(res => {
this.listLoading = false
this.getList(this.req.MONTH)
})*/
},
// 批改
save() {
/* this.listLoading = true
this.$http.post('busprojecttask/findTaskList', this.req).then(res => {
this.listLoading = false
this.getList(this.req.MONTH)
})*/
}
}
}
</script>
<style lang="scss" scoped>
h1{
color: black !important;
text-align: center;
padding: 20px;
}
table{margin-top: 20px;}
.tableClass{
::v-deep .el-table__fixed{height: 100% !important; // 设置高优先,以笼罩内联款式}
}
</style>
table-column.vue
<template>
<el-table-column :label="coloumnHeader.tableHeadName" :prop="coloumnHeader.tableFiled" align="center">
<template v-for="item in coloumnHeader.children">
<tableColumn v-if="item.children && item.children.length" :key="Math.random()" :coloumn-header="item"></tableColumn>
<el-table-column :fixed="item.fixed" :width="item.width?item.width:'auto'"v-else :key="Math.random()":label="item.tableHeadName":prop="item.tableFiled"align="center">
<template slot-scope="scope">
<template v-if="item.isEdit">
<el-select
v-if='(item.htmlType =="select"|| item.htmlType =="radio") && item.dictData'
v-model.lazy="scope.row[item.tableFiled]">
<el-option
v-for="dict in item.dictData"
:key="dict.value"
:label="dict.label"
:value="parseInt(dict.value)"
/>
</el-select>
<el-date-picker
v-else-if='item.htmlType =="datetime"&& item.queryType !="BETWEEN"'clearable size="small"v-model.lazy="scope.row[item.tableFiled]"type="date"value-format="yyyy-MM-dd">
</el-date-picker>
<el-date-picker
v-else-if='item.htmlType =="datetime"&& item.queryType =="BETWEEN"'v-model.lazy="scope.row[item.tableFiled]"size="small"style="width: 240px"value-format="yyyy-MM-dd"type="daterange"range-separator="-"start-placeholder=" 开始日期 "end-placeholder=" 完结日期 "
></el-date-picker>
<el-input-number
v-else-if='item.htmlType =="number"'v-model.lazy="scope.row[item.tableFiled]"
clearable
size="small"
/>
<el-input
v-else
v-model.lazy="scope.row[item.tableFiled]"
clearable
size="small"
/>
</template>
<template v-else-if="item.template">
{{getTemplate(item.template,scope)}}
</template>
<template v-else>
<dict-tag v-if="item.dictData" :options="item.dictData" :value="scope.row[item.tableFiled]" />
<tempalte v-else-if="item.dictDataArray" >
<dict-tag v-for="(it,itIndex) in item.dictDataArray" v-if="scope.row[it.props] == it.value" :key="itIndex" :options="it.dictData" :value="scope.row[item.tableFiled]" />
</tempalte>
<template v-else>{{scope.row[item.tableFiled]}}</template>
</template>
</template>
</el-table-column>
</template>
</el-table-column>
</template>
<script>
export default {
name: 'TableColumn',
props: {
coloumnHeader: {
type: Object,
required: true
}
}
}
</script>
<style scoped>
</style>
父组件
list 为表格数据,tableHeader 为表头数据
<template>
<dynamicHeaderEdit
:tableHeader="tableHeader"
:list="list"
ref="table">
</dynamicHeaderEdit>
</template>
正文完