✨(component): 新增 table 复杂表头实现
This commit is contained in:
parent
8c9078b0fc
commit
db1c78f458
@ -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;
|
||||||
|
@ -91,53 +91,101 @@ 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) => {
|
||||||
if(column.children) {
|
if (column.children) {
|
||||||
findFindNode(column.children);
|
findFindNode(column.children);
|
||||||
} else {
|
} else {
|
||||||
tableBodyColumns.value.push(column);
|
tableBodyColumns.value.push(column);
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
findFindNode(tableColumns.value)
|
findFindNode(tableColumns.value);
|
||||||
|
|
||||||
const tableColumnKeys = ref<any[]>([]);
|
const tableColumnKeys = ref<any[]>([]);
|
||||||
|
|
||||||
const findFindNodes = (columns: any[]) => {
|
const findFindNodes = (columns: any[]) => {
|
||||||
columns.forEach((column) => {
|
columns.forEach((column) => {
|
||||||
if(column.children) {
|
if (column.children) {
|
||||||
findFindNodes(column.children);
|
findFindNodes(column.children);
|
||||||
} else {
|
} else {
|
||||||
if(!column.hide) {
|
if (!column.hide) {
|
||||||
tableColumnKeys.value.push(column.key);
|
tableColumnKeys.value.push(column.key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
findFindNodes(tableColumns.value)
|
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
|
// 设置 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 {
|
} else {
|
||||||
// 设置 colspan
|
// 设置 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,71 +586,80 @@ const renderTotalRowCell = (column: any) => {
|
|||||||
</template>
|
</template>
|
||||||
</colgroup>
|
</colgroup>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<template v-for="(tableHeadColumn, tableHeadColumnIndex) in tableHeadColumns" :key="tableHeadColumnIndex">
|
||||||
<template
|
<tr>
|
||||||
v-for="(column, columnIndex) in columns"
|
<template
|
||||||
:key="column"
|
v-for="(column, columnIndex) in tableHeadColumn"
|
||||||
>
|
:key="column"
|
||||||
<th
|
|
||||||
v-if="tableColumnKeys.includes(column.key)"
|
|
||||||
class="layui-table-cell"
|
|
||||||
:class="[
|
|
||||||
renderFixedClassName(column, columnIndex),
|
|
||||||
column.fixed ? `layui-table-fixed-${column.fixed}` : '',
|
|
||||||
column.type == 'checkbox'
|
|
||||||
? 'layui-table-cell-checkbox'
|
|
||||||
: '',
|
|
||||||
column.type == 'radio' ? 'layui-table-cell-radio' : '',
|
|
||||||
column.type == 'number'
|
|
||||||
? 'layui-table-cell-number'
|
|
||||||
: '',
|
|
||||||
]"
|
|
||||||
:style="[
|
|
||||||
{
|
|
||||||
textAlign: column.align,
|
|
||||||
},
|
|
||||||
renderFixedStyle(column, columnIndex),
|
|
||||||
]"
|
|
||||||
>
|
>
|
||||||
<template v-if="column.type == 'checkbox'">
|
<th
|
||||||
<lay-checkbox
|
:colspan="column.colspan"
|
||||||
v-model="hasChecked"
|
:rowspan="column.rowspan"
|
||||||
:is-indeterminate="!allChecked"
|
class="layui-table-cell"
|
||||||
skin="primary"
|
:class="[
|
||||||
value="all"
|
renderFixedClassName(column, columnIndex),
|
||||||
@change="changeAll"
|
column.fixed
|
||||||
/>
|
? `layui-table-fixed-${column.fixed}`
|
||||||
</template>
|
: '',
|
||||||
<template v-else>
|
column.type == 'checkbox'
|
||||||
<span>
|
? 'layui-table-cell-checkbox'
|
||||||
<template v-if="column.titleSlot">
|
: '',
|
||||||
<slot :name="column.titleSlot"></slot>
|
column.type == 'radio'
|
||||||
</template>
|
? 'layui-table-cell-radio'
|
||||||
<template v-else>
|
: '',
|
||||||
{{ column.title }}
|
column.type == 'number'
|
||||||
</template>
|
? 'layui-table-cell-number'
|
||||||
</span>
|
: '',
|
||||||
<!-- 插槽 -->
|
]"
|
||||||
<span
|
:style="[
|
||||||
v-if="column.sort"
|
{
|
||||||
class="layui-table-sort layui-inline"
|
textAlign: column.align,
|
||||||
lay-sort
|
},
|
||||||
>
|
renderFixedStyle(column, columnIndex),
|
||||||
<i
|
]"
|
||||||
@click.stop="sortTable($event, column.key, 'asc')"
|
>
|
||||||
class="layui-edge layui-table-sort-asc"
|
<template v-if="column.type == 'checkbox'">
|
||||||
title="升序"
|
<lay-checkbox
|
||||||
></i>
|
v-model="hasChecked"
|
||||||
<i
|
:is-indeterminate="!allChecked"
|
||||||
@click.stop="sortTable($event, column.key, 'desc')"
|
skin="primary"
|
||||||
class="layui-edge layui-table-sort-desc"
|
value="all"
|
||||||
title="降序"
|
@change="changeAll"
|
||||||
></i>
|
/>
|
||||||
</span>
|
</template>
|
||||||
</template>
|
<template v-else>
|
||||||
</th>
|
<span>
|
||||||
</template>
|
<template v-if="column.titleSlot">
|
||||||
</tr>
|
<slot :name="column.titleSlot"></slot>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
{{ column.title }}
|
||||||
|
</template>
|
||||||
|
</span>
|
||||||
|
<!-- 插槽 -->
|
||||||
|
<span
|
||||||
|
v-if="column.sort"
|
||||||
|
class="layui-table-sort layui-inline"
|
||||||
|
lay-sort
|
||||||
|
>
|
||||||
|
<i
|
||||||
|
@click.stop="sortTable($event, column.key, 'asc')"
|
||||||
|
class="layui-edge layui-table-sort-asc"
|
||||||
|
title="升序"
|
||||||
|
></i>
|
||||||
|
<i
|
||||||
|
@click.stop="
|
||||||
|
sortTable($event, column.key, 'desc')
|
||||||
|
"
|
||||||
|
class="layui-edge layui-table-sort-desc"
|
||||||
|
title="降序"
|
||||||
|
></i>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</th>
|
||||||
|
</template>
|
||||||
|
</tr>
|
||||||
|
</template>
|
||||||
</thead>
|
</thead>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
@ -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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user