javascript"><template><div style="padding: 20px"><vxe-table border :data="list" :height="800" :span-method="rowspanMethod"><vxe-column title="一级类目" field="category1"><template #default="{ row }"><a-space><span>{{ row.category1 }}</span><a-button @click="toggleCategoryExpand(row, '1')">{{ showText(row, '1') ? '收起' : '展开' }}</a-button></a-space></template></vxe-column><vxe-column title="二级类目" field="category2"><template #default="{ row }"><a-space><span>{{ row.category2 }}</span><a-buttonv-if="showText(row, '1')"@click="toggleCategoryExpand(row, '2')">{{ showText(row, '2') ? '收起' : '展开' }}</a-button></a-space></template></vxe-column><vxe-column title="三级类目" field="category3"></vxe-column><vxe-column title="报告金额" field="amount"></vxe-column><vxe-column title="合计" field="total"></vxe-column></vxe-table></div>
</template><script>
import { defineComponent, ref } from 'vue'
import XEUtils from 'xe-utils'export default defineComponent({setup() {const flattenedData = [{id: '0',category: '人工成本',parentId: null},{id: '0-0',parentId: '0',category: '人工成本0-0'},{id: '0-0-0',parentId: '0-0',category: '人工成本0-0-0'},{id: '0-0-1',parentId: '0-0',category: '人工成本0-0-1'},{id: '0-1',parentId: '0',category: '人工成本0-1'},{id: '0-1-0',parentId: '0-1',category: '人工成本0-1-0'},{id: '0-1-1',parentId: '0-1',category: '人工成本0-1-1'}]const treeData = XEUtils.toArrayTree(flattenedData)const treeDataTemp = JSON.parse(JSON.stringify(treeData))const renderTreeData = ref(treeDataTemp)const list = ref([])const toColTreeData = (treeData) => {const options = { children: 'children' }const list = []const keyMap = {}XEUtils.eachTree(treeData,(item, index, result, paths, parent) => {keyMap[item.id] = itemitem.keys = parent ? parent.keys.concat([item.id]) : [item.id]if (!item.children || !item.children.length) {const row = {}item.keys.forEach((key, index) => {const level = index + 1const obj = keyMap[key]row[`category${level}`] = obj.categoryrow[`id${level}`] = obj.id})list.push(row)}},options)return list}const rowspanMethod = ({ row, _rowIndex, column, visibleData }) => {const fields = ['category1', 'category2']const cellValue = row[column.field]if (cellValue && fields.includes(column.field)) {const prevRow = visibleData[_rowIndex - 1]let nextRow = visibleData[_rowIndex + 1]if (prevRow && prevRow[column.field] === cellValue) {return { rowspan: 0, colspan: 0 }} else {let countRowspan = 1while (nextRow && nextRow[column.field] === cellValue) {nextRow = visibleData[++countRowspan + _rowIndex]}if (countRowspan > 1) {return { rowspan: countRowspan, colspan: 1 }}}}}renderTreeData.value.forEach((item) => {if (item.children.length) {item.children = []}})list.value = toColTreeData(renderTreeData.value)const toggleCategoryExpand = (row, level) => {if (level === '1') {toggleLevelOne(row)}if (level === '2') {toggleLevelTwo(row)}}const toggleLevelOne = (row) => {const { id1 } = rowconst item = renderTreeData.value.find((item) => item.id === id1)if (item.children.length) {item.children = []} else {const a = treeData.find((item) => item.id === id1)item.children = JSON.parse(JSON.stringify(a.children))item.children.forEach((child) => {child.children = []})}list.value = toColTreeData(renderTreeData.value)}const toggleLevelTwo = (row) => {const { id1, id2 } = rowconst item1 = renderTreeData.value.find((item) => item.id === id1)const item2 = item1.children.find((item) => item.id === id2)if (item2.children.length) {item2.children = []} else {const a1 = treeData.find((item) => item.id === id1)const a2 = a1.children.find((item) => item.id === id2)item2.children = a2.children}list.value = toColTreeData(renderTreeData.value)}const showText = (row, level) => {const { id1, id2 } = rowif (level === '1') {const item = renderTreeData.value.find((item) => item.id === id1)if (item) {return item.children.length}return false}if (level === '2') {const item1 = renderTreeData.value.find((item) => item.id === id1)const item2 = item1.children.find((item) => item.id === id2)if (item2) {return item2.children.length}return false}}return {rowspanMethod,toggleCategoryExpand,list,showText}}
})
</script>
