开发中碰到了一个复杂的表格,多级表头嵌套,可编辑,动态传入操作按钮,没找到合适的插件,就自己开发了一个 效果截图如下
原型图截图如下,算是100%还原原型图了(部分敏感信息已马赛克,保密,我们是专业的)
先看组件部分
index.vue
<template>
<div >
<el-table
ref="tab"
:show-summary="isShowSum"
:data="tableData"
:height="height"
@selection-change="handleSelectionChange"
style="width: 100%"
>
<el-table-column
v-if="isShowBox"
type="selection"
width="55"/>
<template>
<column-item
v-for="item in col"
:key="item.label"
:col="item"
v-on="$listeners"
/>
</template>
<template
v-if="operates"
>
<el-table-column
ref="fixedColumn"
:width="operates.width"
:fixed="operates.fixed"
label="操作"
:align="operates.align"
>
<template slot-scope="scope">
<div class="operate-group">
<template v-for="(btn, leftOpkey) in operates.list">
<el-button
:type="btn.type"
size="small"
:code="btn.code"
@click="btn.method(scope.$index, scope.row, $event)"
>{{ btn.title }}</el-button>
</template>
</div>
</template>
</el-table-column>
</template>
<template #empty>
<div class="empty"
style="height: 200px">
<span class="empty-desc">暂无数据</span>
</div>
</template>
</el-table>
</div>
</template>
<script>
import ColumnItem from "./column";
export default {
name: "TableItem",
components: {
ColumnItem,
},
props: {
operates: {
type: Object,
default: () => {
return {}
}
},
//表格数据
tableData: {
type: Array,
default: () => [],
},
//表头数据
col: {
type: Array,
default: () => [],
},
//是否在表格下方显示合计
isShowSum: {
type: Boolean,
default: false,
},
//判断单元格文字是居中还是左对齐显示,默认居中
alignType: {
type: String,
default: "center",
},
//设置表格高度,固定表头
height: {
type: String,
default: null, //默认不固定表头
},
//判断是否显示多选框
isShowBox: {
type: Boolean,
default: false, //默认不展示
},
},
data() {
return {
};
},
created() {},
mounted() {
},
methods: {
handleSelectionChange(row){
console.log(row)
}
},
};
</script>
<style>
/* 处理表格表头和内容错位问题 */
.el-table th.gutter {
display: table-cell !important;
}
.el-table th,
.el-table td {
padding: 7px 0 !important;
}
</style>
column.vue
<template>
<el-table-column
:prop="col.field"
:label="col.title"
:align="alignType"
:fixed="col.fixed"
:width="col.width || ''"
>
<template v-for="(item, index) of col.children">
<!--这么写再来多少级嵌套都不怕了-->
<column-item v-if="item.children"
:key="index" :col="item" v-on="$listeners" />
<el-table-column
v-else-if="item.inputType == 'edit'"
:label="item.title"
:key="index + item.field"
:width="col.width || ''"
>
<template slot-scope="scope">
<el-input
v-model="scope.row[item.field]"
@change="changeAmount(scope.row, item.field)"
>
<i slot="suffix"
class="el-icon-edit el-input__icon" />
</el-input>
</template>
</el-table-column>
<el-table-column
v-else
:key="index"
:label="item.title"
:prop="item.field"
:align="alignType"
:width="col.width || ''"
/>
</template>
</el-table-column>
</template>
<script>
export default {
name: "ColumnItem",
props: {
col: {
type: Object,
default: () => [],
},
//判断单元格文字是居中还是左对齐显示
alignType: {
type: String,
default: "left", //默认居中
},
},
methods: {
async changeAmount(row) {
this.$emit('postArr',row)
},
},
};
</script>
表头数据示例
export const column1 = [
{
id: 1,
title: '销售任务',
field: 'data1',
width: 0,
inputType: 'read'
}, {
id: 2,
title: '月销售额',
field: 'data2',
width: 0,
inputType: 'read',
children: [
{
id: 3,
title: '1月销售额',
field: 'sales1',
width: 0,
inputType: 'read',
},
{
id: 4,
title: '2月销售额',
field: 'sales2',
width: 0,
inputType: 'read',
},
{
id: 5,
title: '3月销售额',
field: 'sales3',
width: 0,
inputType: 'read',
}
]
},
{
id: 7,
title: '增长率',
field: '',
width: 0,
inputType: 'read',
children: [
{
id: 8,
title: '1季度',
field: '',
width: 0,
inputType: 'read',
children: [
{
id: 9,
title: '1月',
field: 'month1SalesGrowthRatio',
width: 0,
inputType: 'read',
},
{
id: 10,
title: '2月',
field: 'month2SalesGrowthRatio',
width: 0,
inputType: 'read',
},
{
id: 11,
title: '3月',
field: 'month3SalesGrowthRatio',
width: 0,
inputType: 'read',
}
]
}
]
},
{
id: 12,
title: '销售目标预测',
field: '',
width: 0,
inputType: 'read',
children:[
{
id: 13,
title: '1月',
field: 'predictMonth1',
width: 0,
inputType: 'edit',
},
]
}
]
页面应用(数据都是随便写的)
<template>
<div>
<h3>多表头嵌套,内容可编辑</h3>
<tableTree :col="column1" :table-data="tableData" :operates="operates" @postArr="postArr" />
</div>
</template>
<script>
import tableTree from "@/components/table-tree";
import { column1 } from "./js/table-column";
export default {
components: { tableTree },
data() {
return {
column1,
//如果后台返回的是二维数组需要自己转化下哦
tableData: [
{
data1: "100000",
sales1: "566",
sales2: "236",
sales3: "522",
month1SalesGrowthRatio: "0%",
month2SalesGrowthRatio: "30%",
month3SalesGrowthRatio: "20%",
predictMonth1: "800",
},
{
data1: "200000",
sales1: "23",//这销售额老板会打人的吧
sales2: "45",
sales3: "565",
month1SalesGrowthRatio: "30%",
month2SalesGrowthRatio: "30%",
month3SalesGrowthRatio: "50%",
predictMonth1: "800",
},
],
operates: {
width: 150,
fixed: "right",
list: [
{
title: "编辑",
type:'text',
method: (index, row) => {
this.editRole(row);
},
code: "ui",
},
{
title: "删除",
type:'primary',
method: (index, row) => {
this.deleteRole(row);
},
code: "ui",
},
],
},
};
},
methods: {
postArr(row) {
this.$message({
type: "success",
message: "修改成功!",
});
},
deleteRole(row){
this.$message({
type: "success",
message: "删除成功!",
});
},
editRole(row){
this.$message({
type: "success",
message: "编辑成功!",
});
}
},
};
</script>
<style scoped>
h3 {
text-align: left;
}
</style>
拿走不谢~