refactor: tree
parent
5f189f534e
commit
94aa0df8d7
|
@ -1,33 +1,21 @@
|
||||||
import type { ExtractPropTypes, PropType, VNode } from 'vue';
|
import { ExtractPropTypes, nextTick, onUpdated, PropType, ref, watch } from 'vue';
|
||||||
import { defineComponent, inject } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import omit from 'omit.js';
|
|
||||||
import debounce from 'lodash-es/debounce';
|
import debounce from 'lodash-es/debounce';
|
||||||
import FolderOpenOutlined from '@ant-design/icons-vue/FolderOpenOutlined';
|
import FolderOpenOutlined from '@ant-design/icons-vue/FolderOpenOutlined';
|
||||||
import FolderOutlined from '@ant-design/icons-vue/FolderOutlined';
|
import FolderOutlined from '@ant-design/icons-vue/FolderOutlined';
|
||||||
import FileOutlined from '@ant-design/icons-vue/FileOutlined';
|
import FileOutlined from '@ant-design/icons-vue/FileOutlined';
|
||||||
import PropTypes from '../_util/vue-types';
|
|
||||||
import classNames from '../_util/classNames';
|
import classNames from '../_util/classNames';
|
||||||
import { treeProps } from './Tree';
|
import { AntdTreeNodeAttribute, treeProps } from './Tree';
|
||||||
import Tree, { TreeProps } from './Tree';
|
import Tree, { TreeProps } from './Tree';
|
||||||
import {
|
|
||||||
calcRangeKeys,
|
|
||||||
getFullKeyList,
|
|
||||||
convertDirectoryKeysToNodes,
|
|
||||||
getFullKeyListByTreeData,
|
|
||||||
} from './util';
|
|
||||||
import { getOptionProps, getComponent, getSlot } from '../_util/props-util';
|
|
||||||
import initDefaultProps from '../_util/props-util/initDefaultProps';
|
import initDefaultProps from '../_util/props-util/initDefaultProps';
|
||||||
import { defaultConfigProvider } from '../config-provider';
|
import { convertDataToEntities, convertTreeToData } from '../vc-tree/utils/treeUtil';
|
||||||
|
import { DataNode, EventDataNode, Key } from '../vc-tree/interface';
|
||||||
|
import { conductExpandParent } from '../vc-tree/util';
|
||||||
|
import { calcRangeKeys, convertDirectoryKeysToNodes } from './utils/dictUtil';
|
||||||
|
import useConfigInject from '../_util/hooks/useConfigInject';
|
||||||
|
import { filterEmpty } from '../_util/props-util';
|
||||||
|
|
||||||
export type ExpandAction = false | 'click' | 'doubleClick' | 'dblclick';
|
export type ExpandAction = false | 'click' | 'doubleclick' | 'dblclick';
|
||||||
|
|
||||||
function getIcon(props: { isLeaf: boolean; expanded: boolean } & VNode) {
|
|
||||||
const { isLeaf, expanded } = props;
|
|
||||||
if (isLeaf) {
|
|
||||||
return <FileOutlined />;
|
|
||||||
}
|
|
||||||
return expanded ? <FolderOpenOutlined /> : <FolderOutlined />;
|
|
||||||
}
|
|
||||||
|
|
||||||
const directoryTreeProps = {
|
const directoryTreeProps = {
|
||||||
...treeProps(),
|
...treeProps(),
|
||||||
|
@ -36,6 +24,14 @@ const directoryTreeProps = {
|
||||||
|
|
||||||
export type DirectoryTreeProps = Partial<ExtractPropTypes<typeof directoryTreeProps>>;
|
export type DirectoryTreeProps = Partial<ExtractPropTypes<typeof directoryTreeProps>>;
|
||||||
|
|
||||||
|
function getIcon(props: AntdTreeNodeAttribute) {
|
||||||
|
const { isLeaf, expanded } = props;
|
||||||
|
if (isLeaf) {
|
||||||
|
return <FileOutlined />;
|
||||||
|
}
|
||||||
|
return expanded ? <FolderOpenOutlined /> : <FolderOutlined />;
|
||||||
|
}
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'ADirectoryTree',
|
name: 'ADirectoryTree',
|
||||||
inheritAttrs: false,
|
inheritAttrs: false,
|
||||||
|
@ -43,9 +39,234 @@ export default defineComponent({
|
||||||
showIcon: true,
|
showIcon: true,
|
||||||
expandAction: 'click',
|
expandAction: 'click',
|
||||||
}),
|
}),
|
||||||
setup() {
|
slots: ['icon', 'title', 'switcherIcon'],
|
||||||
|
emits: [
|
||||||
|
'update:selectedKeys',
|
||||||
|
'update:checkedKeys',
|
||||||
|
'update:expandedKeys',
|
||||||
|
'expand',
|
||||||
|
'select',
|
||||||
|
'check',
|
||||||
|
'doubleclick',
|
||||||
|
'dblclick',
|
||||||
|
'click',
|
||||||
|
],
|
||||||
|
setup(props, { attrs, slots, emit }) {
|
||||||
|
// convertTreeToData 兼容 a-tree-node 历史写法,未来a-tree-node移除后,删除相关代码,不要再render中调用 treeData,否则死循环
|
||||||
|
const treeData = ref<DataNode[]>(
|
||||||
|
props.treeData || convertTreeToData(filterEmpty(slots.default?.())),
|
||||||
|
);
|
||||||
|
watch(
|
||||||
|
() => props.treeData,
|
||||||
|
() => {
|
||||||
|
treeData.value = props.treeData;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
onUpdated(() => {
|
||||||
|
nextTick(() => {
|
||||||
|
if (props.treeData === undefined && slots.default) {
|
||||||
|
treeData.value = convertTreeToData(filterEmpty(slots.default?.()));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
// Shift click usage
|
||||||
|
const lastSelectedKey = ref<Key>();
|
||||||
|
|
||||||
|
const cachedSelectedKeys = ref<Key[]>();
|
||||||
|
|
||||||
|
const treeRef = ref();
|
||||||
|
|
||||||
|
const getInitExpandedKeys = () => {
|
||||||
|
const { keyEntities } = convertDataToEntities(treeData.value);
|
||||||
|
|
||||||
|
let initExpandedKeys: any;
|
||||||
|
|
||||||
|
// Expanded keys
|
||||||
|
if (props.defaultExpandAll) {
|
||||||
|
initExpandedKeys = Object.keys(keyEntities);
|
||||||
|
} else if (props.defaultExpandParent) {
|
||||||
|
initExpandedKeys = conductExpandParent(
|
||||||
|
props.expandedKeys || props.defaultExpandedKeys,
|
||||||
|
keyEntities,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
initExpandedKeys = props.expandedKeys || props.defaultExpandedKeys;
|
||||||
|
}
|
||||||
|
return initExpandedKeys;
|
||||||
|
};
|
||||||
|
|
||||||
|
const selectedKeys = ref(props.selectedKeys || props.defaultSelectedKeys || []);
|
||||||
|
|
||||||
|
const expandedKeys = ref<Key[]>(getInitExpandedKeys());
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.selectedKeys,
|
||||||
|
() => {
|
||||||
|
if (props.selectedKeys !== undefined) {
|
||||||
|
selectedKeys.value = props.selectedKeys;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ immediate: true },
|
||||||
|
);
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.expandedKeys,
|
||||||
|
() => {
|
||||||
|
if (props.expandedKeys !== undefined) {
|
||||||
|
expandedKeys.value = props.expandedKeys;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ immediate: true },
|
||||||
|
);
|
||||||
|
|
||||||
|
const expandFolderNode = (event: MouseEvent, node: any) => {
|
||||||
|
const { isLeaf } = node;
|
||||||
|
|
||||||
|
if (isLeaf || event.shiftKey || event.metaKey || event.ctrlKey) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Call internal rc-tree expand function
|
||||||
|
// https://github.com/ant-design/ant-design/issues/12567
|
||||||
|
treeRef.value!.onNodeExpand(event as any, node);
|
||||||
|
};
|
||||||
|
const onDebounceExpand = debounce(expandFolderNode, 200, {
|
||||||
|
leading: true,
|
||||||
|
});
|
||||||
|
const onExpand = (
|
||||||
|
keys: Key[],
|
||||||
|
info: {
|
||||||
|
node: EventDataNode;
|
||||||
|
expanded: boolean;
|
||||||
|
nativeEvent: MouseEvent;
|
||||||
|
},
|
||||||
|
) => {
|
||||||
|
if (props.expandedKeys === undefined) {
|
||||||
|
expandedKeys.value = keys;
|
||||||
|
}
|
||||||
|
// Call origin function
|
||||||
|
emit('update:expandedKeys', keys);
|
||||||
|
emit('expand', keys, info);
|
||||||
|
};
|
||||||
|
|
||||||
|
const onClick = (event: MouseEvent, node: EventDataNode) => {
|
||||||
|
const { expandAction } = props;
|
||||||
|
|
||||||
|
// Expand the tree
|
||||||
|
if (expandAction === 'click') {
|
||||||
|
onDebounceExpand(event, node);
|
||||||
|
}
|
||||||
|
emit('click', event, node);
|
||||||
|
};
|
||||||
|
|
||||||
|
const onDoubleClick = (event: MouseEvent, node: EventDataNode) => {
|
||||||
|
const { expandAction } = props;
|
||||||
|
// Expand the tree
|
||||||
|
if (expandAction === 'dblclick' || expandAction === 'doubleclick') {
|
||||||
|
onDebounceExpand(event, node);
|
||||||
|
}
|
||||||
|
|
||||||
|
emit('doubleclick', event, node);
|
||||||
|
emit('dblclick', event, node);
|
||||||
|
};
|
||||||
|
|
||||||
|
const onSelect = (
|
||||||
|
keys: Key[],
|
||||||
|
event: {
|
||||||
|
event: 'select';
|
||||||
|
selected: boolean;
|
||||||
|
node: any;
|
||||||
|
selectedNodes: DataNode[];
|
||||||
|
nativeEvent: MouseEvent;
|
||||||
|
},
|
||||||
|
) => {
|
||||||
|
const { multiple } = props;
|
||||||
|
const { node, nativeEvent } = event;
|
||||||
|
const { key = '' } = node;
|
||||||
|
|
||||||
|
// const newState: DirectoryTreeState = {};
|
||||||
|
|
||||||
|
// We need wrap this event since some value is not same
|
||||||
|
const newEvent: any = {
|
||||||
|
...event,
|
||||||
|
selected: true, // Directory selected always true
|
||||||
|
};
|
||||||
|
|
||||||
|
// Windows / Mac single pick
|
||||||
|
const ctrlPick: boolean = nativeEvent.ctrlKey || nativeEvent.metaKey;
|
||||||
|
const shiftPick: boolean = nativeEvent.shiftKey;
|
||||||
|
|
||||||
|
// Generate new selected keys
|
||||||
|
let newSelectedKeys: Key[];
|
||||||
|
if (multiple && ctrlPick) {
|
||||||
|
// Control click
|
||||||
|
newSelectedKeys = keys;
|
||||||
|
lastSelectedKey.value = key;
|
||||||
|
cachedSelectedKeys.value = newSelectedKeys;
|
||||||
|
newEvent.selectedNodes = convertDirectoryKeysToNodes(treeData.value, newSelectedKeys);
|
||||||
|
} else if (multiple && shiftPick) {
|
||||||
|
// Shift click
|
||||||
|
newSelectedKeys = Array.from(
|
||||||
|
new Set([
|
||||||
|
...(cachedSelectedKeys.value || []),
|
||||||
|
...calcRangeKeys({
|
||||||
|
treeData: treeData.value,
|
||||||
|
expandedKeys: expandedKeys.value,
|
||||||
|
startKey: key,
|
||||||
|
endKey: lastSelectedKey.value,
|
||||||
|
}),
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
newEvent.selectedNodes = convertDirectoryKeysToNodes(treeData.value, newSelectedKeys);
|
||||||
|
} else {
|
||||||
|
// Single click
|
||||||
|
newSelectedKeys = [key];
|
||||||
|
lastSelectedKey.value = key;
|
||||||
|
cachedSelectedKeys.value = newSelectedKeys;
|
||||||
|
newEvent.selectedNodes = convertDirectoryKeysToNodes(treeData.value, newSelectedKeys);
|
||||||
|
}
|
||||||
|
|
||||||
|
emit('update:selectedKeys', newSelectedKeys);
|
||||||
|
emit('select', newSelectedKeys, newEvent);
|
||||||
|
if (props.selectedKeys === undefined) {
|
||||||
|
selectedKeys.value = newSelectedKeys;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const onCheck: TreeProps['onCheck'] = (checkedObjOrKeys, eventObj) => {
|
||||||
|
emit('update:checkedKeys', checkedObjOrKeys);
|
||||||
|
emit('check', checkedObjOrKeys, eventObj);
|
||||||
|
};
|
||||||
|
|
||||||
|
const { prefixCls, direction } = useConfigInject('tree', props);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
return null;
|
const connectClassName = classNames(
|
||||||
|
`${prefixCls.value}-directory`,
|
||||||
|
{
|
||||||
|
[`${prefixCls.value}-directory-rtl`]: direction.value === 'rtl',
|
||||||
|
},
|
||||||
|
attrs.class,
|
||||||
|
);
|
||||||
|
const { icon = slots.icon, ...otherProps } = props;
|
||||||
|
return (
|
||||||
|
<Tree
|
||||||
|
{...attrs}
|
||||||
|
icon={icon || getIcon}
|
||||||
|
ref={treeRef}
|
||||||
|
blockNode
|
||||||
|
{...otherProps}
|
||||||
|
prefixCls={prefixCls.value}
|
||||||
|
class={connectClassName}
|
||||||
|
expandedKeys={expandedKeys.value}
|
||||||
|
selectedKeys={selectedKeys.value}
|
||||||
|
onSelect={onSelect}
|
||||||
|
onClick={onClick}
|
||||||
|
onDblclick={onDoubleClick}
|
||||||
|
onExpand={onExpand}
|
||||||
|
onCheck={onCheck}
|
||||||
|
v-slots={slots}
|
||||||
|
/>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -150,13 +150,18 @@ export default defineComponent({
|
||||||
'expand',
|
'expand',
|
||||||
'select',
|
'select',
|
||||||
'check',
|
'check',
|
||||||
|
'doubleclick',
|
||||||
|
'dblclick',
|
||||||
],
|
],
|
||||||
TreeNode,
|
TreeNode,
|
||||||
setup(props, { attrs, expose, emit, slots }) {
|
setup(props, { attrs, expose, emit, slots }) {
|
||||||
const { prefixCls, direction, virtual } = useConfigInject('tree', props);
|
const { prefixCls, direction, virtual } = useConfigInject('tree', props);
|
||||||
const tree = ref();
|
const treeRef = ref();
|
||||||
expose({
|
expose({
|
||||||
tree,
|
treeRef,
|
||||||
|
onNodeExpand: (...args) => {
|
||||||
|
treeRef.value?.onNodeExpand(...args);
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleCheck: TreeProps['onCheck'] = (checkedObjOrKeys, eventObj) => {
|
const handleCheck: TreeProps['onCheck'] = (checkedObjOrKeys, eventObj) => {
|
||||||
|
@ -197,7 +202,7 @@ export default defineComponent({
|
||||||
itemHeight={20}
|
itemHeight={20}
|
||||||
virtual={virtual.value}
|
virtual={virtual.value}
|
||||||
{...newProps}
|
{...newProps}
|
||||||
ref={tree}
|
ref={treeRef}
|
||||||
prefixCls={prefixCls.value}
|
prefixCls={prefixCls.value}
|
||||||
class={classNames(
|
class={classNames(
|
||||||
{
|
{
|
||||||
|
|
|
@ -55,7 +55,7 @@ export default defineComponent({
|
||||||
allowDrop: () => true,
|
allowDrop: () => true,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
setup(props, { attrs, slots }) {
|
setup(props, { attrs, slots, expose }) {
|
||||||
const destroyed = ref(false);
|
const destroyed = ref(false);
|
||||||
let delayedDragEnterLogic: Record<Key, number> = {};
|
let delayedDragEnterLogic: Record<Key, number> = {};
|
||||||
const indent = ref();
|
const indent = ref();
|
||||||
|
@ -543,9 +543,9 @@ export default defineComponent({
|
||||||
};
|
};
|
||||||
|
|
||||||
const onNodeDoubleClick: NodeMouseEventHandler = (e, treeNode) => {
|
const onNodeDoubleClick: NodeMouseEventHandler = (e, treeNode) => {
|
||||||
const { onDblClick } = props;
|
const { onDblclick } = props;
|
||||||
if (onDblClick) {
|
if (onDblclick) {
|
||||||
onDblClick(e, treeNode);
|
onDblclick(e, treeNode);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -953,7 +953,9 @@ export default defineComponent({
|
||||||
onKeyDown(event);
|
onKeyDown(event);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
expose({
|
||||||
|
onNodeExpand,
|
||||||
|
});
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
window.removeEventListener('dragend', onWindowDragEnd);
|
window.removeEventListener('dragend', onWindowDragEnd);
|
||||||
destroyed.value = true;
|
destroyed.value = true;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import type { ComputedRef, CSSProperties, Ref, VNode } from 'vue';
|
import type { ComputedRef, CSSProperties, DefineComponent, Ref, VNode } from 'vue';
|
||||||
|
import { TreeNodeProps } from './props';
|
||||||
export type { ScrollTo } from '../vc-virtual-list/List';
|
export type { ScrollTo } from '../vc-virtual-list/List';
|
||||||
|
|
||||||
export interface DataNode {
|
export interface DataNode {
|
||||||
|
@ -39,7 +40,7 @@ export type IconType = any;
|
||||||
|
|
||||||
export type Key = string | number;
|
export type Key = string | number;
|
||||||
|
|
||||||
export type NodeElement = VNode & {
|
export type NodeElement = VNode<DefineComponent<TreeNodeProps>> & {
|
||||||
type: {
|
type: {
|
||||||
isTreeNode: boolean;
|
isTreeNode: boolean;
|
||||||
};
|
};
|
||||||
|
|
|
@ -149,7 +149,7 @@ export const treeProps = () => ({
|
||||||
onKeyDown: { type: Function as PropType<EventHandlerNonNull> },
|
onKeyDown: { type: Function as PropType<EventHandlerNonNull> },
|
||||||
onContextmenu: { type: Function as PropType<EventHandlerNonNull> },
|
onContextmenu: { type: Function as PropType<EventHandlerNonNull> },
|
||||||
onClick: { type: Function as PropType<NodeMouseEventHandler> },
|
onClick: { type: Function as PropType<NodeMouseEventHandler> },
|
||||||
onDblClick: { type: Function as PropType<NodeMouseEventHandler> },
|
onDblclick: { type: Function as PropType<NodeMouseEventHandler> },
|
||||||
onScroll: { type: Function as PropType<EventHandlerNonNull> },
|
onScroll: { type: Function as PropType<EventHandlerNonNull> },
|
||||||
onExpand: {
|
onExpand: {
|
||||||
type: Function as PropType<
|
type: Function as PropType<
|
||||||
|
|
|
@ -64,7 +64,7 @@ export function warningWithoutKey(treeData: DataNode[], fieldNames: FieldNames)
|
||||||
* Convert `children` of Tree into `treeData` structure.
|
* Convert `children` of Tree into `treeData` structure.
|
||||||
*/
|
*/
|
||||||
export function convertTreeToData(rootNodes: VNodeChild): DataNode[] {
|
export function convertTreeToData(rootNodes: VNodeChild): DataNode[] {
|
||||||
function dig(node: VNodeChild): DataNode[] {
|
function dig(node: VNodeChild = []): DataNode[] {
|
||||||
const treeNodes = node as NodeElement[];
|
const treeNodes = node as NodeElement[];
|
||||||
return treeNodes
|
return treeNodes
|
||||||
.map(treeNode => {
|
.map(treeNode => {
|
||||||
|
@ -75,8 +75,8 @@ export function convertTreeToData(rootNodes: VNodeChild): DataNode[] {
|
||||||
}
|
}
|
||||||
|
|
||||||
const key = treeNode.key as string | number;
|
const key = treeNode.key as string | number;
|
||||||
const { children, ...rest } = treeNode.props;
|
const { ...rest } = treeNode.props;
|
||||||
|
const children = (treeNode.children as any)?.default?.();
|
||||||
const dataNode: DataNode = {
|
const dataNode: DataNode = {
|
||||||
...rest,
|
...rest,
|
||||||
key,
|
key,
|
||||||
|
|
|
@ -1,45 +1,30 @@
|
||||||
<template>
|
<template>
|
||||||
<a-tree
|
<a-directory-tree
|
||||||
v-model:expandedKeys="expandedKeys"
|
v-model:expandedKeys="expandedKeys"
|
||||||
v-model:selectedKeys="selectedKeys"
|
v-model:selectedKeys="selectedKeys"
|
||||||
:load-data="onLoadData"
|
multiple
|
||||||
:tree-data="treeData"
|
@test="onTest"
|
||||||
/>
|
>
|
||||||
|
<a-tree-node key="0-0" title="parent 0">
|
||||||
|
<a-tree-node key="0-0-0" title="leaf 0-0" is-leaf />
|
||||||
|
<a-tree-node key="0-0-1" title="leaf 0-1" is-leaf />
|
||||||
|
</a-tree-node>
|
||||||
|
<a-tree-node key="0-1" title="parent 1">
|
||||||
|
<a-tree-node key="0-1-0" title="leaf 1-0" is-leaf />
|
||||||
|
<a-tree-node key="0-1-1" title="leaf 1-1" is-leaf />
|
||||||
|
</a-tree-node>
|
||||||
|
</a-directory-tree>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent, ref } from 'vue';
|
import { defineComponent, ref } from 'vue';
|
||||||
import { TreeDataItem } from 'ant-design-vue/es/tree/Tree';
|
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
setup() {
|
setup() {
|
||||||
const expandedKeys = ref<string[]>([]);
|
const expandedKeys = ref<string[]>(['0-0', '0-1']);
|
||||||
const selectedKeys = ref<string[]>([]);
|
const selectedKeys = ref<string[]>([]);
|
||||||
const treeData = ref<TreeDataItem[]>([
|
|
||||||
{ title: 'Expand to load', key: '0' },
|
|
||||||
{ title: 'Expand to load', key: '1' },
|
|
||||||
{ title: 'Tree Node', key: '2', isLeaf: true },
|
|
||||||
]);
|
|
||||||
const onLoadData = (treeNode: any) => {
|
|
||||||
return new Promise((resolve: (value?: unknown) => void) => {
|
|
||||||
if (treeNode.dataRef.children) {
|
|
||||||
resolve();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setTimeout(() => {
|
|
||||||
treeNode.dataRef.children = [
|
|
||||||
{ title: 'Child Node', key: `${treeNode.eventKey}-0` },
|
|
||||||
{ title: 'Child Node', key: `${treeNode.eventKey}-1` },
|
|
||||||
];
|
|
||||||
treeData.value = [...treeData.value];
|
|
||||||
resolve();
|
|
||||||
}, 1000);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
return {
|
return {
|
||||||
expandedKeys,
|
expandedKeys,
|
||||||
selectedKeys,
|
selectedKeys,
|
||||||
treeData,
|
onTest: () => {},
|
||||||
onLoadData,
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue