数据:
export default [ { id: '5829341', projectName: '资本化支出', remark: '1', childNode: [ { id: '5829342', parentId: '5829341', projectName: '设备购置', money: 660000.00, remark: '固定资产' }, { id: '5829343', parentId: '5829341', projectName: '软件购置', money: 660000.00, remark: '无形资产' } ] }, { id: '5829344', projectName: '费用化支出', remark: '费用化支出', childNode: [ { id: '5829345', parentId: '5829344', projectName: '材料费', remark: '物料消耗、低值易耗品摊销、办公用品' }, { id: '5829346', parentId: '5829344', projectName: '燃料动力费', remark: '燃料,外购燃料,燃料油,汽油,柴油,其他燃料油,燃料气,天然气,外购动力等费用,其他,电(一般不予填写)' }, { id: '5829371', parentId: '5829344', projectName: '人员费', remark: '员工费用,工资,福利等费用,不超过35%,误餐补贴' }, { id: '5829372', parentId: '5829344', projectName: '管理费', remark: '上级管理费,不超过5%' }, { id: '5829373', parentId: '5829344', projectName: '结转', remark: '月末结转' }, { id: '5829347', parentId: '5829344', projectName: '其他直接费', childNode: [ { id: '5829361', parentId: '5829347', projectName: '技术服务费', remark: '技术服务费,外协费,其他,' }, { id: '5829362', parentId: '5829347', projectName: '办公费', remark: '办公费,印刷费,通讯费,电话费,其他通讯费用,发票费用,邮电费,路桥、停车费,其他办公费用,团体会费(不包含办公用品)' }, { id: '5829363', parentId: '5829347', projectName: '差旅费', remark: '差旅费,外埠差旅费,市内交通费,市内住宿费,飞机票,住宿补贴,其他,考察联络费(参加会议发生在各项支出)' }, { id: '5829364', parentId: '5829347', projectName: '会议费', remark: '会议费,内部会议费,外部会议费(主办会议发生的各项支出)' }, { id: '5829365', parentId: '5829347', projectName: '国际合作与交流费', remark: '外宾招待费,出国人员经费' }, { id: '5829366', parentId: '5829347', projectName: '业务招待费', remark: '业务招待费' }, { id: '5829367', parentId: '5829347', projectName: '劳务费', remark: '劳务费,有偿解除劳动合同人员返聘劳务费,其他劳务费(不予填写)' }, { id: '5829368', parentId: '5829347', projectName: '科研机构', remark: ' ' }, { id: '5829369', parentId: '5829347', projectName: '其他费用', remark: '团体会费' }, { id: '5829370', parentId: '5829347', projectName: '预算外费用', remark: '预算外费用,折旧折耗摊销,固定资产折旧,投资性房地产折旧,无形资产摊销等(不予填写)' }, { id: '5829348', parentId: '5829347', projectName: '条件配套费', childNode: [ { id: '5829349', parentId: '5829348', projectName: '租赁费', remark: '租赁费,土地租赁费,房屋租赁费,油槽车租赁费,通信线路租赁费等租赁费用' }, { id: '5829350', parentId: '5829348', projectName: '维护及修理费', remark: '维护及修理费,房屋建筑物修理费,热力设施维修费,车辆修理费,信息系统维护费等,道路维修费' }, { id: '5829351', parentId: '5829348', projectName: '取暖费', remark: '取暖费,不超过2.5%' }, { id: '5829352', parentId: '5829348', projectName: '物业管理费', remark: '物业管理费,绿化及环境卫生费,警卫消防费,不超过7.5%' }, { id: '5829353', parentId: '5829348', projectName: '运输费', remark: '运输费,一次运费,铁路运费,公路运费,海上运费,管道运费等运输费用' } ] }, { id: '5829354', parentId: '5829347', projectName: '技术配套费', childNode: [ { id: '5829355', parentId: '5829354', projectName: '测试化验加工', remark: '外部加工费,检测费,试验检验费,测试化验加工,试验检验费' }, { id: '5829356', parentId: '5829354', projectName: '设计制图费', remark: '设计制图费' }, { id: '5829357', parentId: '5829354', projectName: '资料解释费', remark: '资料解释费' }, { id: '5829358', parentId: '5829354', projectName: '出版/文献/信息传播/知识产权事务费', remark: '图书资料费,出版/文献/信息传播/知识产权事务费' }, { id: '5829359', parentId: '5829354', projectName: '培训费', remark: '其他费用,培训费,国家项目劳务费,研究生经费,国际合作交流费,其他' }, { id: '5829360', parentId: '5829354', projectName: '咨询评审费', remark: '咨询审计费,审计费,评估费,法律费用,市场调查费,咨询费,其他' } ] } ] } ] } ]
html
<el-table ref="table" :data="tableList" :show-header="true" border size="mini" :span-method="arraySpanMethod" show-summary :summary-method="getSummaries" :header-cell-style="hideHeader" > <el-table-column prop="index" label="序号" width="60" header-align="center" align="center" > <template slot-scope="scope">{{ scope.row.repertory }}</template> </el-table-column> <el-table-column label="项目分类" header-align="center"> <el-table-column v-for="item in titleKey" :key="item" :prop="item" label /> </el-table-column> <el-table-column prop="expense" label="预算经费(单位:元)" width="180" header-align="center" align="right" > <template slot-scope="scope"> <el-input-number v-model="scope.row.expense" :min="0" :step="1" style="width:100%" :controls="false" :disabled="!receiveInfo" placeholder="请输入费用化预算(万元" size="mini" /> </template> </el-table-column> <el-table-column prop="remark" label="备注" header-align="center" show-overflow-tooltip /> </el-table>
data定义的数据
data() { return { resultList: [], nameMap: {}, titleKey: [], backUpItem: Object.create(null), treeList, treeMap: {}, tableList: [], matrixMap: {} } },
事件
created() { console.log(this.treeList) this.initData(this.treeList) const tableList = this.initTableList() for (let i = 0; i < tableList.length; i++) { for (let j = 0; j < this.titleKey.length + 3; j++) { if (j === 0) { if (this.nameMap[tableList[i]['index']]) { this.matrixMap[`${i}${j}`] = [ this.nameMap[tableList[i]['index']].row - 1, 1 ] } else { this.matrixMap[`${i}${j}`] = [0, 0] } } else if (j > 0 && j <= this.titleKey.length) { if (tableList[i][`key${j}`]) { this.matrixMap[`${i}${j}`] = [ this.nameMap[tableList[i][`key${j}`]].row > 1 ? this.nameMap[tableList[i][`key${j}`]].row - 1 : this.nameMap[tableList[i][`key${j}`]].row, this.nameMap[tableList[i][`key${j}`]].col ] } else { this.matrixMap[`${i}${j}`] = [0, 0] } } else { this.matrixMap[`${i}${j}`] = [1, 1] } } } this.tableList = tableList }, methods: { arraySpanMethod({ row, column, rowIndex, columnIndex }) { return this.matrixMap[`${rowIndex}${columnIndex}`] }, handleSetCol(item, rank) { // 设置父元素跨了多少行 递归设置 因为所有的父元素跨的行都相应的增加 item.row = item.row + 1 // 这里需要递归进行设置祖先元素 this.handleSetRow(item.rank, rank + 1 - item.rank) if (this.treeMap[item.parentId]) { this.handleSetCol(this.treeMap[item.parentId], rank) } }, handleSetRow(rank, col) { // 设置所有对应的rank层级的元素垮了多少列 Object.values(this.treeMap).forEach(item => { if (item.rank === rank && !item.childNode && item.rank != 1) { item.col = col } }) }, initData(list, step) { // 递归保证下面层序遍历生成的数组还是有序的 const sortList = list => { list.forEach(item => { if (Array.isArray(item.childNode)) { sortList(item.childNode) } else { this.resultList.push(this.treeMap[item.id]) } }) } // 层序遍历 // 当前层级便利的队列 let queue = [...this.treeList] // 下一个层级要遍历的队列 let nextQueue = [] let rank = 0 while (queue.length) { const len = queue.length for (let i = 0; i < len; i++) { const item = queue[i] item.rank = rank + 1 if (!item.col) { item.row = 1 item.col = 1 } // id =》 item // name => item this.treeMap[item.id] = item this.nameMap[item.projectName] = item // 找到度为0的孩子节点 if (this.treeMap[item.parentId] && !item.childNode) { // 设置父元素所占 this.handleSetCol(this.treeMap[item.parentId], rank + 1) } if (Array.isArray(item.childNode)) { nextQueue = nextQueue.concat(item.childNode) } } queue = JSON.parse(JSON.stringify(nextQueue)) nextQueue = [] rank++ // 确定循环的key this.titleKey.push(`key${rank}`) // 确定循环的对象 this.backUpItem[`key${rank}`] = '' } Object.values(this.treeMap).forEach((item, index) => { !item.parentId && sortList(item.childNode) }) }, initItem(item, ret) { ret[`key${item.rank}`] = item.projectName item.isSet = true if (!item.parentId) { ret.index = item.projectName } return item.parentId && !this.treeMap[item.parentId].isSet ? this.initItem(this.treeMap[item.parentId], ret) : ret }, getRootId(id) { if (!this.treeMap[id].parentId) { return this.treeMap[id] } return this.getRootId(this.treeMap[id].parentId) }, initTableList() { const result = [] let currentIndex = 0 this.resultList.forEach(item => { const ret = { ...this.backUpItem, money: item.money ? item.money : 0, remark: item.remark, id: item.id } // 判断有多少个rank = 1 的项 就有多少个item if ( !this.treeMap[item.parentId].isIndex && this.treeMap[item.parentId].rank === 1 ) { ++currentIndex this.treeMap[item.parentId].isIndex = true } ret.repertory = currentIndex result.push(this.initItem(item, ret)) }) console.log(result, 'result') return result }, getSummaries(param) { const { columns, data } = param const sums = [] columns.forEach((column, index) => { if (index === this.titleKey.length + 1) { let ret = 0 data.forEach(item => { ret += item.money }) sums[index] = ret } else if (index !== 0) { sums[index] = '' } else { sums[index] = '合计' } }) this.$nextTick(() => { this.$refs['table'].doLayout() }) return sums }, // 写到请求后端数据里 transformationList() { // this.projectForecast 后端请求到的树形数据 this.initData(this.projectForecast) const tableList = this.initTableList() for (let i = 0; i < tableList.length; i++) { for (let j = 0; j < this.titleKey.length + 6; j++) { console.log(this.matrixMap[`row${i}-col${j}`], 'aaaa') if (j === 0) { if (this.nameMap[tableList[i]['index']]) { this.matrixMap[`row${i}-col${j}`] = [ this.nameMap[tableList[i]['index']].row - 1, 1 ] } else { this.matrixMap[`row${i}-col${j}`] = [0, 0] } } else if (j > 0 && j <= this.titleKey.length) { if (tableList[i][`key${j}`]) { this.matrixMap[`row${i}-col${j}`] = [ this.nameMap[tableList[i][`key${j}`]].row > 1 ? this.nameMap[tableList[i][`key${j}`]].row - 1 : this.nameMap[tableList[i][`key${j}`]].row, this.nameMap[tableList[i][`key${j}`]].col ] } else { this.matrixMap[`row${i}-col${j}`] = [0, 0] } } else { this.matrixMap[`row${i}-col${j}`] = [1, 1] } } } this.tableList = tableList } }
注意: 树形数据 首层不能有parentId,
a