Skip to content

Commit

Permalink
[Table] fix expandAll problem; support props.expandedTreeNodes contro…
Browse files Browse the repository at this point in the history
…l expanded nodes (Tencent#2719)

* feat(table): support table expand

* fix(table): expand all

* docs(table): update

* fix: lint error

* fix(table): expandOnRowClick and selectOnRowClick conflict

* feat(table): add removeChildren
  • Loading branch information
chaishi authored and methodchen committed Aug 25, 2023
1 parent da30758 commit 5e71e54
Show file tree
Hide file tree
Showing 13 changed files with 356 additions and 918 deletions.
2 changes: 1 addition & 1 deletion src/_common
Submodule _common updated 1 files
+126 −20 js/table/tree-store.ts
2 changes: 1 addition & 1 deletion src/popup/plugin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ const removeOverlayInstance = () => {
}
};

export type PluginMethod = (triggerEl: string, content: TNode, popupProps?: TdPopupProps) => Instance;
export type PluginMethod = (triggerEl: string | HTMLElement, content: TNode, popupProps?: TdPopupProps) => Instance;

export const createPopupPlugin: PluginMethod = (trigger, content, popupProps) => {
const hasTrigger = triggerType(popupProps?.trigger || 'hover');
Expand Down
59 changes: 35 additions & 24 deletions src/table/_example/tree.vue
Original file line number Diff line number Diff line change
@@ -1,25 +1,23 @@
<template>
<div>
<div>
<t-space>
<t-button @click="appendToRoot">添加根节点</t-button>
<t-button theme="default" style="margin-left: 16px" @click="resetData">重置/更新数据</t-button>
<t-button theme="default" style="margin-left: 16px" @click="onRowToggle">任意节点展开/收起</t-button>
<t-button theme="default" style="margin-left: 16px" @click="onExpandAllToggle">{{
expandAll ? '收起全部' : '展开全部'
}}</t-button>
<t-button theme="default" style="margin-left: 16px" @click="getTreeNode">获取全部树形结构</t-button>
</div>
<t-button theme="default" @click="resetData">重置/更新数据</t-button>
<t-button theme="default" @click="onRowToggle">任意节点展开/收起</t-button>
<t-button theme="default" @click="onExpandAllToggle">{{ expandAll ? '收起全部' : '展开全部' }}</t-button>
<t-button theme="default" @click="getTreeNode">获取全部树形结构</t-button>
</t-space>
<br />
<div>
<t-checkbox v-model="customTreeExpandAndFoldIcon" style="vertical-align: middle">
自定义折叠/展开图标
</t-checkbox>
</div>
<br />
<!-- 第一列展开树结点,缩进为 24px,子节点字段 childrenKey 默认为 children -->
<!-- !!! 树形结构 EnhancedTable 才支持,普通 Table 不支持 !!! -->
<!-- Ref: this.$refs.table.dataSource 查看树形结构平铺数据,获取属性结构使用 this.$refs.table.getTreeNode() -->
<!-- 可以使用受控属性 :displayColumns.sync="displayColumns" 完全自由控制显示列 -->
<!-- 第一列展开树结点,缩进为 24px,子节点字段 childrenKey 默认为 children -->
<!-- :displayColumns.sync="displayColumns" used to control displayed columns -->
<!-- expandedTreeNodes.sync is not required. you can control expanded tree node by expandedTreeNodes -->
<t-enhanced-table
ref="table"
rowKey="key"
Expand All @@ -30,6 +28,7 @@
:treeExpandAndFoldIcon="treeExpandIcon"
:pagination="pagination"
:beforeDragSort="beforeDragSort"
:expandedTreeNodes.sync="expandedTreeNodes"
:columnController="{
placement: 'bottom-left',
// 允许控制哪些列显示或隐藏
Expand All @@ -40,8 +39,9 @@
@page-change="onPageChange"
@abnormal-drag-sort="onAbnormalDragSort"
@drag-sort="onDragSort"
@tree-expand-change="onTreeExpandChange"
@expanded-tree-nodes-change="onExpandedTreeNodesChange"
></t-enhanced-table>
<!-- @tree-expand-change="onTreeExpandChange" -->

<!-- 第二列展开树结点,缩进为 12px,示例代码有效,勿删 -->
<!-- indent 定义缩进距离 -->
Expand Down Expand Up @@ -135,6 +135,7 @@ export default {
data,
lazyLoadingData: null,
expandAll: false,
expandedTreeNodes: ['申请人 2_1 号', '申请人 30_1 号', '申请人 4_1 号'],
pagination: {
current: 1,
pageSize: 10,
Expand Down Expand Up @@ -226,16 +227,16 @@ export default {
},
},
// 默认展开全部。示例代码有效,勿删
// mounted() {
// this.$refs.table.expandAll();
// },
methods: {
// 全新赋值
// 全新赋值
resetData() {
this.data = getData();
this.$refs.table.resetData(this.data);
const newData = getData();
// 方式一
this.data = newData;
this.expandedTreeNodes = [];
// 方式二,和方式一等效
// this.$refs.table.resetData(newData);
},
// 更新
Expand All @@ -253,6 +254,8 @@ export default {
// 删除
onDeleteConfirm(row) {
this.$refs.table.remove(row.key);
// 移除子节点
// this.$refs.table.removeChildren(row.key);
this.$message.success('删除成功');
},
Expand Down Expand Up @@ -282,7 +285,7 @@ export default {
appendMultipleDataTo(row) {
const randomKey1 = Math.round(Math.random() * Math.random() * 1000) + 10000;
const randomKey2 = Math.round(Math.random() * Math.random() * 1000) + 10000;
const newData = [
const appendList = [
{
id: randomKey1,
key: `申请人 ${randomKey1}`,
Expand All @@ -296,7 +299,7 @@ export default {
type: 'Number',
},
];
this.$refs.table.appendTo(row?.key, newData);
this.$refs.table.appendTo(row?.key, appendList);
MessagePlugin.success(`已插入子节点申请人 ${randomKey1}${randomKey2} 号,请展开查看`);
},
Expand Down Expand Up @@ -343,7 +346,7 @@ export default {
// eslint-disable-next-line
treeExpandAndFoldIconRender(h, { type, row }) {
if (this.lazyLoadingData && this.lazyLoadingData.id === row?.id) {
if (this.lazyLoadingData && this.lazyLoadingData.key === row?.key) {
return <Loading size="14px" />;
}
return type === 'expand' ? <ChevronRightIcon /> : <ChevronDownIcon />;
Expand All @@ -352,12 +355,18 @@ export default {
// 懒加载图标渲染
lazyLoadingTreeIconRender(h, params) {
const { type, row } = params;
if (this.lazyLoadingData?.id === row?.id) {
if (this.lazyLoadingData?.key === row?.key) {
return <Loading size="14px" />;
}
return type === 'expand' ? <AddRectangleIcon /> : <MinusRectangleIcon />;
},
onExpandedTreeNodesChange(expandedTreeNodes, context) {
console.log(expandedTreeNodes, context);
if (!context.rowState) return;
this.onTreeExpandChange(context);
},
onTreeExpandChange(context) {
console.log(context.rowState.expanded ? '展开' : '收起', context);
/**
Expand All @@ -377,6 +386,8 @@ export default {
},
getTreeNode() {
// 查看树形结构平铺数据
// this.$refs.table.dataSource
const treeData = this.$refs.table.getTreeNode();
console.log(treeData);
this.$message.success('树形结构获取成功,请打开控制台查看');
Expand Down
14 changes: 13 additions & 1 deletion src/table/enhanced-table-props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,16 @@ export default {
beforeDragSort: {
type: Function as PropType<TdEnhancedTableProps['beforeDragSort']>,
},
/** 展开的树形节点。非必须。在需要自由控制展开的树形节点时使用。其他场景无需设置,表格组件有内置展开逻辑 */
expandedTreeNodes: {
type: Array as PropType<TdEnhancedTableProps['expandedTreeNodes']>,
default: undefined,
},
/** 展开的树形节点。非必须。在需要自由控制展开的树形节点时使用。其他场景无需设置,表格组件有内置展开逻辑,非受控属性 */
defaultExpandedTreeNodes: {
type: Array as PropType<TdEnhancedTableProps['defaultExpandedTreeNodes']>,
default: (): TdEnhancedTableProps['defaultExpandedTreeNodes'] => [],
},
/** 树形结构相关配置。具体属性文档查看 `TableTreeConfig` 相关描述 */
tree: {
type: Object as PropType<TdEnhancedTableProps['tree']>,
Expand All @@ -22,6 +32,8 @@ export default {
},
/** 异常拖拽排序时触发,如:树形结构中,非同层级之间的交换。`context.code` 指交换异常错误码,固定值;`context.reason` 指交换异常的原因 */
onAbnormalDragSort: Function as PropType<TdEnhancedTableProps['onAbnormalDragSort']>,
/** 树形结构,用户操作引起节点展开或收起时触发,代码操作不会触发 */
/** 树形结构,展开的树节点发生变化时触发,泛型 T 指表格数据类型 */
onExpandedTreeNodesChange: Function as PropType<TdEnhancedTableProps['onExpandedTreeNodesChange']>,
/** 已废弃。树形结构,用户操作引起节点展开或收起时触发。请更为使用 `onExpandedTreeNodesChange` */
onTreeExpandChange: Function as PropType<TdEnhancedTableProps['onTreeExpandChange']>,
};
67 changes: 31 additions & 36 deletions src/table/hooks/useTreeData.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import {
SetupContext, ref, watch, toRefs, onUnmounted, computed, shallowRef,
} from '@vue/composition-api';
import { AddRectangleIcon as TdAddRectangleIcon, MinusRectangleIcon as TdMinusRectangleIcon } from 'tdesign-icons-vue';
import cloneDeep from 'lodash/cloneDeep';
import get from 'lodash/get';
import { CreateElement } from 'vue';
import TableTreeStore, { SwapParams } from '../../_common/js/table/tree-store';
Expand All @@ -19,6 +18,7 @@ import { renderCell } from '../tr';
import { useConfig } from '../../config-provider/useConfig';
import { useTNodeDefault } from '../../hooks/tnode';
import { useGlobalIcon } from '../../hooks/useGlobalIcon';
import useTreeDataExpand from './useTreeDataExpand';

export default function useTreeData(props: TdEnhancedTableProps, context: SetupContext) {
const { data, columns } = toRefs(props);
Expand All @@ -38,6 +38,14 @@ export default function useTreeData(props: TdEnhancedTableProps, context: SetupC
childrenKey: props.tree?.childrenKey || 'children',
}));

const {
tExpandedTreeNode, expandAll, foldAll, updateExpandOnDataChange, onExpandFoldIconClick,
} = useTreeDataExpand(
props,
context,
{ store, dataSource, rowDataKeys },
);

const checkedColumn = computed(() => columns.value.find((col) => col.colKey === 'row-select'));

watch(checkedColumn, (column) => {
Expand All @@ -63,26 +71,18 @@ export default function useTreeData(props: TdEnhancedTableProps, context: SetupC
});
}

const uniqueKeys = computed(() => store.value?.getAllUniqueKeys(data.value, rowDataKeys.value)?.join() || '');

watch(
[uniqueKeys],
[data],
() => {
if (!data.value) return [];
if (!props.tree) {
if (props.tree) {
resetData(data.value);
} else {
dataSource.value = data.value;
return;
}
resetData(data.value);
},
{ immediate: true },
);

// 不能启用这部分代码。如果启用,会导致选中树形结构子节点时数据被重置,全部节点收起
// watch([columns, rowDataKeys], ([columns, rowDataKeys]) => {
// store.value.initialTreeStore(data.value, columns, rowDataKeys);
// });

onUnmounted(() => {
if (!props.tree) return;
store.value.treeDataMap?.clear();
Expand All @@ -98,12 +98,12 @@ export default function useTreeData(props: TdEnhancedTableProps, context: SetupC
);

function resetData(data: TableRowData[]) {
let newVal = cloneDeep(data);
store.value.initialTreeStore(newVal, props.columns, rowDataKeys.value);
if (props.tree?.defaultExpandAll) {
newVal = store.value.expandAll(newVal, rowDataKeys.value);
store.value.initialTreeStore(data, props.columns, rowDataKeys.value);
if (tExpandedTreeNode.value?.length) {
updateExpandOnDataChange(data);
} else {
dataSource.value = [...data];
}
dataSource.value = newVal;
}

function getTreeNodeStyle(level: number) {
Expand Down Expand Up @@ -162,16 +162,16 @@ export default function useTreeData(props: TdEnhancedTableProps, context: SetupC
const classes = { [tableTreeClasses.inlineCol]: !!col.ellipsis };
const childrenNodes = get(p.row, rowDataKeys.value.childrenKey);
if ((childrenNodes && childrenNodes instanceof Array) || childrenNodes === true) {
const iconNode = store.value.treeDataMap.get(get(p.row, rowDataKeys.value.rowKey))?.expanded
? getFoldIcon(h, p)
: getExpandIcon(h, p);
const expanded = store.value.treeDataMap.get(get(p.row, rowDataKeys.value.rowKey))?.expanded;
const iconNode = expanded ? getFoldIcon(h, p) : getExpandIcon(h, p);
return (
<div class={[tableTreeClasses.col, classes]} style={colStyle}>
{!!(childrenNodes.length || childrenNodes === true) && (
<span
class={tableTreeClasses.icon}
onClick={(e: MouseEvent) => {
toggleExpandData(p, 'expand-fold-icon');
// toggleExpandData(p, 'expand-fold-icon');
onExpandFoldIconClick(p, 'expand-fold-icon');
e.stopPropagation();
}}
>
Expand Down Expand Up @@ -227,6 +227,14 @@ export default function useTreeData(props: TdEnhancedTableProps, context: SetupC
dataSource.value = [...store.value.remove(key, dataSource.value, rowDataKeys.value)];
}

/**
* 移除子节点
* @param key 行唯一标识
*/
function removeChildren(key: TableRowValue) {
dataSource.value = [...store.value.removeChildren(key, dataSource.value, rowDataKeys.value)];
}

/**
* 对外暴露的组件实例方法,为当前节点添加子节点,默认添加到最后一个节点
* @param key 当前节点唯一标识
Expand Down Expand Up @@ -255,20 +263,6 @@ export default function useTreeData(props: TdEnhancedTableProps, context: SetupC
dataSource.value = [...store.value.insertBefore(rowValue, newData, dataSource.value, rowDataKeys.value)];
}

/**
* 对外暴露的组件实例方法,展开所有节点
*/
function expandAll() {
dataSource.value = [...store.value.expandAll(dataSource.value, rowDataKeys.value)];
}

/**
* 对外暴露的组件实例方法,收起所有节点
*/
function foldAll() {
dataSource.value = [...store.value.foldAll(dataSource.value, rowDataKeys.value)];
}

/**
* 对外暴露的组件实例方法,交换行数据
*/
Expand Down Expand Up @@ -310,6 +304,7 @@ export default function useTreeData(props: TdEnhancedTableProps, context: SetupC
setData,
getData,
remove,
removeChildren,
appendTo,
insertAfter,
insertBefore,
Expand Down
Loading

0 comments on commit 5e71e54

Please sign in to comment.