(component): 新增 table 复杂表头实现

This commit is contained in:
就眠儀式 2022-08-08 03:19:11 +08:00
parent 8c9078b0fc
commit db1c78f458
3 changed files with 152 additions and 99 deletions

View File

@ -465,11 +465,6 @@
box-shadow: inset -10px 0 8px -8px #00000026; box-shadow: inset -10px 0 8px -8px #00000026;
} }
.layui-table-view .layui-table tr th:last-child,
.layui-table-view .layui-table tr td:last-child {
border-right: none !important;
}
.layui-table-tool { .layui-table-tool {
position: relative; position: relative;
z-index: 890; z-index: 890;

View File

@ -91,10 +91,41 @@ const hasChecked = ref(false);
const tableDataSource = ref<any[]>([...props.dataSource]); const tableDataSource = ref<any[]>([...props.dataSource]);
const tableColumns = computed(() => { const tableColumns = computed(() => {
return [...props.columns]; return [...props.columns];
}) });
const tableHeadColumns = ref<any[]>([]) const tableHeadColumns = ref<any[]>([]);
const tableBodyColumns = ref<any[]>([]) const tableBodyColumns = ref<any[]>([]);
const getLevel = (arr: any[]) => {
let maxLevel = 0;
(function callBack(arr, level) {
++level;
maxLevel = Math.max(level, maxLevel);
for (let i = 0; i < arr.length; i++) {
let item = arr[i];
if (item.children && item.children.length > 0) {
callBack(item.children, level);
} else {
delete item.children;
}
}
})(arr, 0);
return maxLevel;
};
function getLeafCountTree(json: any) {
if (!json.children || json.children.length == 0) {
json.colspan = 1;
return 1;
} else {
var leafCount = 0;
for (var i = 0; i < json.children.length; i++) {
leafCount = leafCount + getLeafCountTree(json.children[i]);
}
json.colspan = leafCount;
return leafCount;
}
}
const findFindNode = (columns: any[]) => { const findFindNode = (columns: any[]) => {
columns.forEach((column) => { columns.forEach((column) => {
@ -103,10 +134,10 @@ const findFindNode = (columns: any[]) => {
} else { } else {
tableBodyColumns.value.push(column); tableBodyColumns.value.push(column);
} }
}) });
} };
findFindNode(tableColumns.value) findFindNode(tableColumns.value);
const tableColumnKeys = ref<any[]>([]); const tableColumnKeys = ref<any[]>([]);
@ -119,10 +150,10 @@ const findFindNodes = (columns: any[]) => {
tableColumnKeys.value.push(column.key); tableColumnKeys.value.push(column.key);
} }
} }
}) });
} };
findFindNodes(tableColumns.value) findFindNodes(tableColumns.value);
/** /**
* 处理为复杂表头, 待完成 * 处理为复杂表头, 待完成
@ -130,14 +161,31 @@ findFindNodes(tableColumns.value)
* @param level 层级, 用于决定会被 push 到的目标数组 * @param level 层级, 用于决定会被 push 到的目标数组
*/ */
const findFinalNode = (level: number, columns: any[]) => { const findFinalNode = (level: number, columns: any[]) => {
columns.forEach(column => { columns.forEach((column) => {
if (column.children) { if (column.children) {
// rowspan
} else {
// colspan // colspan
const colSpan = getLeafCountTree(column);
column.colspan = colSpan;
column.rowspan = 1;
if (!tableHeadColumns.value[level]) {
tableHeadColumns.value[level] = [];
} }
}) tableHeadColumns.value[level].push(column);
findFinalNode(level + 1, column.children);
} else {
// rowspan
const rowSpan = getLevel(columns);
column.rowspan = rowSpan;
column.colspan = 1;
if (!tableHeadColumns.value[level]) {
tableHeadColumns.value[level] = [];
} }
tableHeadColumns.value[level].push(column);
}
});
};
findFinalNode(0, tableColumns.value);
const tableSelectedKeys = ref<Recordable[]>([...props.selectedKeys]); const tableSelectedKeys = ref<Recordable[]>([...props.selectedKeys]);
const tableExpandKeys = ref<Recordable[]>([...props.expandKeys]); const tableExpandKeys = ref<Recordable[]>([...props.expandKeys]);
@ -538,21 +586,27 @@ const renderTotalRowCell = (column: any) => {
</template> </template>
</colgroup> </colgroup>
<thead> <thead>
<template v-for="(tableHeadColumn, tableHeadColumnIndex) in tableHeadColumns" :key="tableHeadColumnIndex">
<tr> <tr>
<template <template
v-for="(column, columnIndex) in columns" v-for="(column, columnIndex) in tableHeadColumn"
:key="column" :key="column"
> >
<th <th
v-if="tableColumnKeys.includes(column.key)" :colspan="column.colspan"
:rowspan="column.rowspan"
class="layui-table-cell" class="layui-table-cell"
:class="[ :class="[
renderFixedClassName(column, columnIndex), renderFixedClassName(column, columnIndex),
column.fixed ? `layui-table-fixed-${column.fixed}` : '', column.fixed
? `layui-table-fixed-${column.fixed}`
: '',
column.type == 'checkbox' column.type == 'checkbox'
? 'layui-table-cell-checkbox' ? 'layui-table-cell-checkbox'
: '', : '',
column.type == 'radio' ? 'layui-table-cell-radio' : '', column.type == 'radio'
? 'layui-table-cell-radio'
: '',
column.type == 'number' column.type == 'number'
? 'layui-table-cell-number' ? 'layui-table-cell-number'
: '', : '',
@ -594,7 +648,9 @@ const renderTotalRowCell = (column: any) => {
title="升序" title="升序"
></i> ></i>
<i <i
@click.stop="sortTable($event, column.key, 'desc')" @click.stop="
sortTable($event, column.key, 'desc')
"
class="layui-edge layui-table-sort-desc" class="layui-edge layui-table-sort-desc"
title="降序" title="降序"
></i> ></i>
@ -603,6 +659,7 @@ const renderTotalRowCell = (column: any) => {
</th> </th>
</template> </template>
</tr> </tr>
</template>
</thead> </thead>
</table> </table>
</div> </div>

View File

@ -1169,7 +1169,7 @@ export default {
::: demo 通过 `span-method` 属性, 自定义行列合并的逻辑。 ::: demo 通过 `span-method` 属性, 自定义行列合并的逻辑。
<template> <template>
<lay-table :columns="columns27" :data-source="dataSource27"></lay-table> <lay-table :columns="columns29" :data-source="dataSource29"></lay-table>
</template> </template>
<script> <script>
@ -1178,7 +1178,7 @@ import { ref } from 'vue'
export default { export default {
setup() { setup() {
const columns27 = [ const columns29 = [
{ {
title:"名称", title:"名称",
width:"200px", width:"200px",
@ -1188,6 +1188,7 @@ export default {
children: [ children: [
{ title: "省", key: "province", width: "300px", }, { title: "省", key: "province", width: "300px", },
{ title: "市", key: "city", width: "300px", }, { title: "市", key: "city", width: "300px", },
{ title: "区", key: "area", width: "300px", },
] ]
},{ },{
title:"性别", title:"性别",
@ -1204,17 +1205,17 @@ export default {
} }
] ]
const dataSource27 = [ const dataSource29 = [
{id:"1",username:"root",province:"山东",city:"济南", password:"root",sex:"男", age:"18", remark: 'layui - vue谐音类 UI) '}, {id:"1",username:"就眠儀式",province:"山东",city:"济南",area: "高新区", password:"root",sex:"男", age:"18", remark: 'layui - vue谐音类 UI) '},
{id:"2",username:"root",province:"山东",city:"济南", password:"root",sex:"男", age:"18", remark: 'layui - vue谐音类 UI) '}, {id:"2",username:"就眠儀式",province:"山东",city:"济南",area: "高新区", password:"root",sex:"男", age:"18", remark: 'layui - vue谐音类 UI) '},
{id:"3",username:"woow",province:"山东",city:"济南", password:"woow",sex:"男", age:"20", remark: 'layui - vue谐音类 UI) '}, {id:"3",username:"就眠儀式",province:"山东",city:"济南",area: "高新区", password:"woow",sex:"男", age:"20", remark: 'layui - vue谐音类 UI) '},
{id:"4",username:"woow",province:"山东",city:"济南", password:"woow",sex:"男", age:"20", remark: 'layui - vue谐音类 UI) '}, {id:"4",username:"就眠儀式",province:"山东",city:"济南",area: "高新区", password:"woow",sex:"男", age:"20", remark: 'layui - vue谐音类 UI) '},
{id:"5",username:"woow",province:"山东",city:"济南", password:"woow",sex:"男", age:"20", remark: 'layui - vue谐音类 UI) '} {id:"5",username:"就眠儀式",province:"山东",city:"济南",area: "高新区", password:"woow",sex:"男", age:"20", remark: 'layui - vue谐音类 UI) '}
] ]
return { return {
columns27, columns29,
dataSource27, dataSource29,
} }
} }
} }