feat(BasicTable): table enable accordion expand (#3533). resolve #3525

This commit is contained in:
xachary 2024-01-11 15:29:36 +08:00 committed by GitHub
parent 83f16da2d3
commit abae7f3295
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 126 additions and 15 deletions

View File

@ -22,6 +22,7 @@
v-show="getEmptyDataIsShowTable" v-show="getEmptyDataIsShowTable"
@change="handleTableChange" @change="handleTableChange"
@resize-column="setColumnWidth" @resize-column="setColumnWidth"
@expand="handleTableExpand"
> >
<template #[item]="data" v-for="item in Object.keys($slots)" :key="item"> <template #[item]="data" v-for="item in Object.keys($slots)" :key="item">
<slot :name="item" v-bind="data || {}"></slot> <slot :name="item" v-bind="data || {}"></slot>
@ -207,11 +208,8 @@
const { getRowClassName } = useTableStyle(getProps, prefixCls); const { getRowClassName } = useTableStyle(getProps, prefixCls);
const { getExpandOption, expandAll, expandRows, collapseRows, collapseAll } = useTableExpand( const { getExpandOption, expandAll, expandRows, collapseRows, collapseAll, handleTableExpand } =
getProps, useTableExpand(getProps, tableData, emit);
tableData,
emit,
);
const handlers: InnerHandlers = { const handlers: InnerHandlers = {
onColumnsChange: (data: ColumnChangeParam[]) => { onColumnsChange: (data: ColumnChangeParam[]) => {

View File

@ -1,6 +1,6 @@
import type { ComputedRef, Ref } from 'vue'; import type { ComputedRef, Ref } from 'vue';
import type { BasicTableProps } from '../types/table'; import type { BasicTableProps } from '../types/table';
import { computed, unref, ref, toRaw } from 'vue'; import { computed, unref, ref, toRaw, nextTick } from 'vue';
import { ROW_KEY } from '../const'; import { ROW_KEY } from '../const';
export function useTableExpand( export function useTableExpand(
@ -20,8 +20,8 @@ export function useTableExpand(
}); });
const getExpandOption = computed(() => { const getExpandOption = computed(() => {
const { isTreeTable } = unref(propsRef); const { isTreeTable, expandRowByClick } = unref(propsRef);
if (!isTreeTable) return {}; if (!isTreeTable && !expandRowByClick) return {};
return { return {
expandedRowKeys: unref(expandedRowKeys), expandedRowKeys: unref(expandedRowKeys),
@ -43,15 +43,15 @@ export function useTableExpand(
function expandRows(keys: (string | number)[]) { function expandRows(keys: (string | number)[]) {
// use row ID expands the specified table row // use row ID expands the specified table row
const { isTreeTable } = unref(propsRef); const { isTreeTable, expandRowByClick } = unref(propsRef);
if (!isTreeTable) return; if (!isTreeTable && !expandRowByClick) return;
expandedRowKeys.value = [...expandedRowKeys.value, ...keys]; expandedRowKeys.value = [...expandedRowKeys.value, ...keys];
} }
function collapseRows(keys: (string | number)[]) { function collapseRows(keys: (string | number)[]) {
// use row ID collapses the specified table row // use row ID collapses the specified table row
const { isTreeTable } = unref(propsRef); const { isTreeTable, expandRowByClick } = unref(propsRef);
if (!isTreeTable) return; if (!isTreeTable && !expandRowByClick) return;
expandedRowKeys.value = unref(expandedRowKeys).filter((key) => !keys.includes(key)); expandedRowKeys.value = unref(expandedRowKeys).filter((key) => !keys.includes(key));
} }
@ -68,5 +68,66 @@ export function useTableExpand(
return keys; return keys;
} }
return { getExpandOption, expandAll, collapseAll, expandRows, collapseRows }; // 获取展开路径 keys
function getKeyPaths(
records: Recordable[],
rowKey: string,
childrenColumnName: string,
key: string | number,
paths: Array<string | number>,
): boolean {
if (records.findIndex((record) => record[rowKey] === key) > -1) {
paths.push(key);
return true;
} else {
for (const record of records) {
const children = record[childrenColumnName];
if (
Array.isArray(children) &&
getKeyPaths(children, rowKey, childrenColumnName, key, paths)
) {
paths.push(record[rowKey]);
return true;
}
}
}
return false;
}
// 手风琴展开
function expandRowAccordion(key: string | number, rowKey: string) {
const { childrenColumnName } = unref(propsRef);
const paths: Array<string | number> = [];
getKeyPaths(tableData.value, rowKey, childrenColumnName || 'children', key, paths);
expandedRowKeys.value = paths;
}
// 监听展开事件,用于支持手风琴展开效果
function handleTableExpand(expanded, record) {
// 手风琴开关
// isTreeTable 或 expandRowByClick 时支持
// rowKey 是字符串时支持
// 展开操作
if (
propsRef.value.accordion &&
(propsRef.value.isTreeTable || propsRef.value.expandRowByClick) &&
typeof getRowKey.value === 'string' &&
expanded
) {
const rowKey = getRowKey.value as string;
nextTick(() => {
expandRowAccordion(record[rowKey], rowKey);
});
}
}
return {
getExpandOption,
expandAll,
collapseAll,
expandRows,
collapseRows,
expandRowAccordion,
handleTableExpand,
};
} }

View File

@ -148,6 +148,7 @@ export interface BasicTableProps<T = any> {
// 点击行选中 // 点击行选中
clickToRowSelect?: boolean; clickToRowSelect?: boolean;
isTreeTable?: boolean; isTreeTable?: boolean;
accordion?: boolean; // isTreeTable 或 expandRowByClick 时支持
// 自定义排序方法 // 自定义排序方法
sortFn?: (sortInfo: SorterResult) => any; sortFn?: (sortInfo: SorterResult) => any;
// 排序方法 // 排序方法

View File

@ -48,6 +48,7 @@
rowKey: 'id', rowKey: 'id',
canResize: false, canResize: false,
expandRowByClick: true, expandRowByClick: true,
accordion: true, //
actionColumn: { actionColumn: {
width: 160, width: 160,
title: 'Action', title: 'Action',

View File

@ -17,6 +17,7 @@
const [register, { expandAll, collapseAll, expandRows, collapseRows }] = useTable({ const [register, { expandAll, collapseAll, expandRows, collapseRows }] = useTable({
title: '树形表格', title: '树形表格',
isTreeTable: true, isTreeTable: true,
accordion: true, //
rowSelection: { rowSelection: {
type: 'checkbox', type: 'checkbox',
getCheckboxProps(record: Recordable) { getCheckboxProps(record: Recordable) {

View File

@ -294,13 +294,62 @@ export function getTreeTableData() {
endTime: new Date().toLocaleString(), endTime: new Date().toLocaleString(),
children: [ children: [
{ {
id: `l2-${index}`, id: `l2-${index}-1`,
name: 'John Brown', name: 'John Brown',
age: `1${index}`, age: `1`,
no: `${index + 10}`, no: `${index + 10}`,
address: 'New York No. 1 Lake ParkNew York No. 1 Lake Park', address: 'New York No. 1 Lake ParkNew York No. 1 Lake Park',
beginTime: new Date().toLocaleString(), beginTime: new Date().toLocaleString(),
endTime: new Date().toLocaleString(), endTime: new Date().toLocaleString(),
children: [
{
id: `l3-${index}-1-1`,
name: 'John Brown',
age: `11`,
no: `11`,
address: 'New York No. 1 Lake ParkNew York No. 1 Lake Park',
beginTime: new Date().toLocaleString(),
endTime: new Date().toLocaleString(),
},
{
id: `l3-${index}-1-2`,
name: 'John Brown',
age: `12`,
no: `12`,
address: 'New York No. 1 Lake ParkNew York No. 1 Lake Park',
beginTime: new Date().toLocaleString(),
endTime: new Date().toLocaleString(),
},
],
},
{
id: `l2-${index}-2`,
name: 'John Brown',
age: `2`,
no: `${index + 10}`,
address: 'New York No. 1 Lake ParkNew York No. 1 Lake Park',
beginTime: new Date().toLocaleString(),
endTime: new Date().toLocaleString(),
children: [
{
id: `l3-${index}-2-1`,
name: 'John Brown',
age: `21`,
no: `21`,
address: 'New York No. 1 Lake ParkNew York No. 1 Lake Park',
beginTime: new Date().toLocaleString(),
endTime: new Date().toLocaleString(),
},
{
id: `l3-${index}-2-2`,
name: 'John Brown',
age: `22`,
no: `22`,
address: 'New York No. 1 Lake ParkNew York No. 1 Lake Park',
beginTime: new Date().toLocaleString(),
endTime: new Date().toLocaleString(),
},
],
}, },
], ],
}); });