Files
vxe-table/examples/views/table/advanced/SpanRow.vue
2021-08-29 17:07:09 +08:00

375 lines
16 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div>
<p class="tip">实现横向树列表<br><span class="red"><table-api-link prop="span-method"/> 不能用于树形结构展开行固定列合并的逻辑都是自行实现的该示例仅供参考</span></p>
<vxe-table
border
height="600"
:scroll-y="{enabled: false}"
:span-method="rowspanMethod"
:data="tableData">
<vxe-column field="name1" title="功能模块">
<template #default="{ row }">
<vxe-checkbox v-model="row.check1" @change="check1ChangeEvent(row, row.check1)">{{ row.name1 }}</vxe-checkbox>
</template>
</vxe-column>
<vxe-column field="name2" title="详细功能">
<template #default="{ row }">
<vxe-checkbox v-model="row.check2" @change="check2ChangeEvent(row, row.check2)">{{ row.name2 }}</vxe-checkbox>
</template>
</vxe-column>
<vxe-column field="name3" title="权限类型">
<template #default="{ row }">
<vxe-checkbox v-model="row.check3" @change="check3ChangeEvent(row, row.check3)">{{ row.name3 }}</vxe-checkbox>
</template>
</vxe-column>
<vxe-column field="name4" title="权限列表">
<template #default="{ row }">
<vxe-checkbox v-model="row.check4" @change="check4ChangeEvent(row, row.check4)">{{ row.name4 }}</vxe-checkbox>
</template>
</vxe-column>
</vxe-table>
<p class="demo-code">{{ $t('app.body.button.showCode') }}</p>
<pre>
<pre-code class="xml">{{ demoCodes[0] }}</pre-code>
<pre-code class="javascript">{{ demoCodes[1] }}</pre-code>
</pre>
</div>
</template>
<script>
import XEUtils from 'xe-utils'
export default {
data () {
return {
tableData: [],
demoCodes: [
`
<vxe-table
border
height="600"
:scroll-y="{enabled: false}"
:span-method="rowspanMethod"
:data="tableData">
<vxe-column field="name1" title="功能模块">
<template #default="{ row }">
<vxe-checkbox v-model="row.check1" @change="check1ChangeEvent(row, row.check1)">{{ row.name1 }}</vxe-checkbox>
</template>
</vxe-column>
<vxe-column field="name2" title="详细功能">
<template #default="{ row }">
<vxe-checkbox v-model="row.check2" @change="check2ChangeEvent(row, row.check2)">{{ row.name2 }}</vxe-checkbox>
</template>
</vxe-column>
<vxe-column field="name3" title="权限类型">
<template #default="{ row }">
<vxe-checkbox v-model="row.check3" @change="check3ChangeEvent(row, row.check3)">{{ row.name3 }}</vxe-checkbox>
</template>
</vxe-column>
<vxe-column field="name4" title="权限列表">
<template #default="{ row }">
<vxe-checkbox v-model="row.check4" @change="check4ChangeEvent(row, row.check4)">{{ row.name4 }}</vxe-checkbox>
</template>
</vxe-column>
</vxe-table>
`,
`
import XEUtils from 'xe-utils'
export default {
data () {
return {
tableData: []
}
},
created () {
const treeData = XEUtils.toArrayTree(this.getList())
this.toColTreeData(treeData)
},
methods: {
check1ChangeEvent (row, checked) {
const { tableData } = this
let childList = tableData.filter(item => item.name1 === row.name1)
childList.forEach(item => {
item.check1 = checked
})
childList = this.tableData.filter(item => item.id1 === row.id1)
childList.forEach(item => {
this.check2ChangeEvent(item, checked)
})
},
check2ChangeEvent (row, checked) {
const { tableData } = this
let childList = tableData.filter(item => item.id1 === row.id1 && item.name2 === row.name2)
childList.forEach(item => {
item.check2 = checked
})
childList = this.tableData.filter(item => item.id2 === row.id2)
childList.forEach(item => {
this.check3ChangeEvent(item, checked)
})
},
check3ChangeEvent (row, checked) {
const { tableData } = this
let childList = tableData.filter(item => item.id2 === row.id2 && item.name3 === row.name3)
childList.forEach(item => {
item.check3 = checked
})
childList = tableData.filter(item => item.id3 === row.id3)
childList.forEach(item => {
this.check4ChangeEvent(item, checked)
})
},
check4ChangeEvent (row, checked) {
const { tableData } = this
let childList = tableData.filter(item => item.id3 === row.id3 && item.name4 === row.name4)
childList.forEach(item => {
item.check4 = checked
})
childList = tableData.filter(item => item.id3 === row.id3)
const isChecked3 = childList.every(item => item.check4)
childList.forEach(item => {
item.check3 = isChecked3
})
childList = tableData.filter(item => item.id2 === row.id2)
const isChecked2 = childList.every(item => item.check3)
childList.forEach(item => {
item.check2 = isChecked2
})
childList = tableData.filter(item => item.id1 === row.id1)
const isChecked1 = childList.every(item => item.check2)
childList.forEach(item => {
item.check1 = isChecked1
})
},
getList () {
const list = [
{ id: '10000', parentId: null, name: '账号管理' },
{ id: '11000', parentId: '10000', name: '用户管理' },
{ id: '11100', parentId: '11000', name: '查看' },
{ id: '11110', parentId: '11100', name: '用户列表' },
{ id: '11200', parentId: '11000', name: '编辑' },
{ id: '11210', parentId: '11200', name: '用户列表' },
{ id: '11220', parentId: '11200', name: '新增用户' },
{ id: '11300', parentId: '11000', name: '操作' },
{ id: '11310', parentId: '11300', name: '新增' },
{ id: '11320', parentId: '11300', name: '删除' },
{ id: '11330', parentId: '11300', name: '修改' },
{ id: '12000', parentId: '10000', name: '角色管理' },
{ id: '12100', parentId: '12000', name: '查看' },
{ id: '12110', parentId: '12100', name: '角色列表' },
{ id: '12200', parentId: '12000', name: '编辑' },
{ id: '122100', parentId: '12200', name: '角色列表' },
{ id: '12220', parentId: '12200', name: '新增角色' },
{ id: '12300', parentId: '12000', name: '操作' },
{ id: '12310', parentId: '12300', name: '新增' },
{ id: '12320', parentId: '12300', name: '删除' },
{ id: '12330', parentId: '12300', name: '修改' },
{ id: '20000', parentId: null, name: '个人中心' },
{ id: '21000', parentId: '20000', name: '个性化设置' },
{ id: '21100', parentId: '21000', name: '查看' },
{ id: '21110', parentId: '21100', name: '信息列表' },
{ id: '21200', parentId: '21000', name: '操作' },
{ id: '21210', parentId: '21200', name: '重置信息' },
{ id: '22000', parentId: '20000', name: '账户管理' },
{ id: '22100', parentId: '22000', name: '查看' },
{ id: '22110', parentId: '22100', name: '账户余额' },
{ id: '22120', parentId: '22100', name: '帐变记录' }
]
return list
},
// 将普通树结构转换为横向树列表
toColTreeData (treeData) {
const options = { children: 'children' }
const list = []
const keyMap = {}
XEUtils.eachTree(treeData, (item, index, result, paths, parent) => {
keyMap[item.id] = item
item.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 + 1
const obj = keyMap[key]
row[\`check\${level}\`] = false
row[\`id\${level}\`] = obj.id
row[\`name\${level}\`] = obj.name
})
list.push(row)
}
}, options)
this.keyMap = keyMap
this.tableData = list
},
// 通用行合并函数(将相同多列数据合并为一行)
rowspanMethod ({ row, _rowIndex, column, visibleData }) {
const fields = ['name1', 'name2', 'name3']
const cellValue = row[column.property]
if (cellValue && fields.includes(column.property)) {
const prevRow = visibleData[_rowIndex - 1]
let nextRow = visibleData[_rowIndex + 1]
if (prevRow && prevRow[column.property] === cellValue) {
return { rowspan: 0, colspan: 0 }
} else {
let countRowspan = 1
while (nextRow && nextRow[column.property] === cellValue) {
nextRow = visibleData[++countRowspan + _rowIndex]
}
if (countRowspan > 1) {
return { rowspan: countRowspan, colspan: 1 }
}
}
}
}
}
}
`
]
}
},
created () {
const treeData = XEUtils.toArrayTree(this.getList())
this.toColTreeData(treeData)
},
methods: {
check1ChangeEvent (row, checked) {
const { tableData } = this
let childList = tableData.filter(item => item.name1 === row.name1)
childList.forEach(item => {
item.check1 = checked
})
childList = this.tableData.filter(item => item.id1 === row.id1)
childList.forEach(item => {
this.check2ChangeEvent(item, checked)
})
},
check2ChangeEvent (row, checked) {
const { tableData } = this
let childList = tableData.filter(item => item.id1 === row.id1 && item.name2 === row.name2)
childList.forEach(item => {
item.check2 = checked
})
childList = this.tableData.filter(item => item.id2 === row.id2)
childList.forEach(item => {
this.check3ChangeEvent(item, checked)
})
},
check3ChangeEvent (row, checked) {
const { tableData } = this
let childList = tableData.filter(item => item.id2 === row.id2 && item.name3 === row.name3)
childList.forEach(item => {
item.check3 = checked
})
childList = tableData.filter(item => item.id3 === row.id3)
childList.forEach(item => {
this.check4ChangeEvent(item, checked)
})
},
check4ChangeEvent (row, checked) {
const { tableData } = this
let childList = tableData.filter(item => item.id3 === row.id3 && item.name4 === row.name4)
childList.forEach(item => {
item.check4 = checked
})
childList = tableData.filter(item => item.id3 === row.id3)
const isChecked3 = childList.every(item => item.check4)
childList.forEach(item => {
item.check3 = isChecked3
})
childList = tableData.filter(item => item.id2 === row.id2)
const isChecked2 = childList.every(item => item.check3)
childList.forEach(item => {
item.check2 = isChecked2
})
childList = tableData.filter(item => item.id1 === row.id1)
const isChecked1 = childList.every(item => item.check2)
childList.forEach(item => {
item.check1 = isChecked1
})
},
getList () {
const list = [
{ id: '10000', parentId: null, name: '账号管理' },
{ id: '11000', parentId: '10000', name: '用户管理' },
{ id: '11100', parentId: '11000', name: '查看' },
{ id: '11110', parentId: '11100', name: '用户列表' },
{ id: '11200', parentId: '11000', name: '编辑' },
{ id: '11210', parentId: '11200', name: '用户列表' },
{ id: '11220', parentId: '11200', name: '新增用户' },
{ id: '11300', parentId: '11000', name: '操作' },
{ id: '11310', parentId: '11300', name: '新增' },
{ id: '11320', parentId: '11300', name: '删除' },
{ id: '11330', parentId: '11300', name: '修改' },
{ id: '12000', parentId: '10000', name: '角色管理' },
{ id: '12100', parentId: '12000', name: '查看' },
{ id: '12110', parentId: '12100', name: '角色列表' },
{ id: '12200', parentId: '12000', name: '编辑' },
{ id: '122100', parentId: '12200', name: '角色列表' },
{ id: '12220', parentId: '12200', name: '新增角色' },
{ id: '12300', parentId: '12000', name: '操作' },
{ id: '12310', parentId: '12300', name: '新增' },
{ id: '12320', parentId: '12300', name: '删除' },
{ id: '12330', parentId: '12300', name: '修改' },
{ id: '20000', parentId: null, name: '个人中心' },
{ id: '21000', parentId: '20000', name: '个性化设置' },
{ id: '21100', parentId: '21000', name: '查看' },
{ id: '21110', parentId: '21100', name: '信息列表' },
{ id: '21200', parentId: '21000', name: '操作' },
{ id: '21210', parentId: '21200', name: '重置信息' },
{ id: '22000', parentId: '20000', name: '账户管理' },
{ id: '22100', parentId: '22000', name: '查看' },
{ id: '22110', parentId: '22100', name: '账户余额' },
{ id: '22120', parentId: '22100', name: '帐变记录' }
]
return list
},
// 将普通树结构转换为横向树列表
toColTreeData (treeData) {
const options = { children: 'children' }
const list = []
const keyMap = {}
XEUtils.eachTree(treeData, (item, index, result, paths, parent) => {
keyMap[item.id] = item
item.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 + 1
const obj = keyMap[key]
row[`check${level}`] = false
row[`id${level}`] = obj.id
row[`name${level}`] = obj.name
})
list.push(row)
}
}, options)
this.keyMap = keyMap
this.tableData = list
},
// 通用行合并函数(将相同多列数据合并为一行)
rowspanMethod ({ row, _rowIndex, column, visibleData }) {
const fields = ['name1', 'name2', 'name3']
const cellValue = row[column.property]
if (cellValue && fields.includes(column.property)) {
const prevRow = visibleData[_rowIndex - 1]
let nextRow = visibleData[_rowIndex + 1]
if (prevRow && prevRow[column.property] === cellValue) {
return { rowspan: 0, colspan: 0 }
} else {
let countRowspan = 1
while (nextRow && nextRow[column.property] === cellValue) {
nextRow = visibleData[++countRowspan + _rowIndex]
}
if (countRowspan > 1) {
return { rowspan: countRowspan, colspan: 1 }
}
}
}
}
}
}
</script>