Files
vxe-table/examples/views/table/advanced/SpanRow.vue

395 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="demo1.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="typescript">{{ demoCodes[1] }}</pre-code>
</pre>
</div>
</template>
<script lang="ts">
import { defineComponent, reactive } from 'vue'
import { VxeTablePropTypes } from '../../../../types/index'
import XEUtils from 'xe-utils'
export default defineComponent({
setup () {
const demo1 = reactive({
tableData: [] as any[]
})
const check4ChangeEvent = (row: any, checked: boolean) => {
let childList = demo1.tableData.filter(item => item.id3 === row.id3 && item.name4 === row.name4)
childList.forEach(item => {
item.check4 = checked
})
childList = demo1.tableData.filter(item => item.id3 === row.id3)
const isChecked3 = childList.every(item => item.check4)
childList.forEach(item => {
item.check3 = isChecked3
})
childList = demo1.tableData.filter(item => item.id2 === row.id2)
const isChecked2 = childList.every(item => item.check3)
childList.forEach(item => {
item.check2 = isChecked2
})
childList = demo1.tableData.filter(item => item.id1 === row.id1)
const isChecked1 = childList.every(item => item.check2)
childList.forEach(item => {
item.check1 = isChecked1
})
}
const check3ChangeEvent = (row: any, checked: boolean) => {
let childList = demo1.tableData.filter(item => item.id2 === row.id2 && item.name3 === row.name3)
childList.forEach(item => {
item.check3 = checked
})
childList = demo1.tableData.filter(item => item.id3 === row.id3)
childList.forEach(item => {
check4ChangeEvent(item, checked)
})
}
const check2ChangeEvent = (row: any, checked: boolean) => {
let childList = demo1.tableData.filter(item => item.id1 === row.id1 && item.name2 === row.name2)
childList.forEach(item => {
item.check2 = checked
})
childList = demo1.tableData.filter(item => item.id2 === row.id2)
childList.forEach(item => {
check3ChangeEvent(item, checked)
})
}
const check1ChangeEvent = (row: any, checked: boolean) => {
let childList = demo1.tableData.filter(item => item.name1 === row.name1)
childList.forEach(item => {
item.check1 = checked
})
childList = demo1.tableData.filter(item => item.id1 === row.id1)
childList.forEach(item => {
check2ChangeEvent(item, checked)
})
}
const 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
}
// 将普通树结构转换为横向树列表
const toColTreeData = (treeData: any[]) => {
const options = { children: 'children' }
const list: any[] = []
const keyMap: any = {}
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: any = {}
item.keys.forEach((key: any, index: number) => {
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)
demo1.tableData = list
}
// 通用行合并函数(将相同多列数据合并为一行)
const rowspanMethod: VxeTablePropTypes.SpanMethod = ({ 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 }
}
}
}
}
const treeData = XEUtils.toArrayTree(getList())
toColTreeData(treeData)
return {
demo1,
check1ChangeEvent,
check2ChangeEvent,
check3ChangeEvent,
check4ChangeEvent,
rowspanMethod,
demoCodes: [
`
<vxe-table
border
height="600"
:scroll-y="{enabled: false}"
:span-method="rowspanMethod"
:data="demo1.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 { defineComponent, reactive } from 'vue'
import { VxeTablePropTypes } from 'vxe-table'
import XEUtils from 'xe-utils'
export default defineComponent({
setup () {
const demo1 = reactive({
tableData: [] as any[]
})
const check4ChangeEvent = (row: any, checked: boolean) => {
let childList = demo1.tableData.filter(item => item.id3 === row.id3 && item.name4 === row.name4)
childList.forEach(item => {
item.check4 = checked
})
childList = demo1.tableData.filter(item => item.id3 === row.id3)
const isChecked3 = childList.every(item => item.check4)
childList.forEach(item => {
item.check3 = isChecked3
})
childList = demo1.tableData.filter(item => item.id2 === row.id2)
const isChecked2 = childList.every(item => item.check3)
childList.forEach(item => {
item.check2 = isChecked2
})
childList = demo1.tableData.filter(item => item.id1 === row.id1)
const isChecked1 = childList.every(item => item.check2)
childList.forEach(item => {
item.check1 = isChecked1
})
}
const check3ChangeEvent = (row: any, checked: boolean) => {
let childList = demo1.tableData.filter(item => item.id2 === row.id2 && item.name3 === row.name3)
childList.forEach(item => {
item.check3 = checked
})
childList = demo1.tableData.filter(item => item.id3 === row.id3)
childList.forEach(item => {
check4ChangeEvent(item, checked)
})
}
const check2ChangeEvent = (row: any, checked: boolean) => {
let childList = demo1.tableData.filter(item => item.id1 === row.id1 && item.name2 === row.name2)
childList.forEach(item => {
item.check2 = checked
})
childList = demo1.tableData.filter(item => item.id2 === row.id2)
childList.forEach(item => {
check3ChangeEvent(item, checked)
})
}
const check1ChangeEvent = (row: any, checked: boolean) => {
let childList = demo1.tableData.filter(item => item.name1 === row.name1)
childList.forEach(item => {
item.check1 = checked
})
childList = demo1.tableData.filter(item => item.id1 === row.id1)
childList.forEach(item => {
check2ChangeEvent(item, checked)
})
}
const 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
}
// 将普通树结构转换为横向树列表
const toColTreeData = (treeData: any[]) => {
const options = { children: 'children' }
const list: any[] = []
const keyMap: any = {}
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: any = {}
item.keys.forEach((key: any, index: number) => {
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)
demo1.tableData = list
}
// 通用行合并函数(将相同多列数据合并为一行)
const rowspanMethod: VxeTablePropTypes.SpanMethod = ({ 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 }
}
}
}
}
const treeData = XEUtils.toArrayTree(getList())
toColTreeData(treeData)
return {
demo1,
check1ChangeEvent,
check2ChangeEvent,
check3ChangeEvent,
check4ChangeEvent,
rowspanMethod
}
}
})
`
]
}
}
})
</script>