diff --git a/devui/tree/src/composables/use-merge-node.ts b/devui/tree/src/composables/use-merge-node.ts new file mode 100644 index 0000000000000000000000000000000000000000..b5c8db7d460823f1bdbc4cd34e46395912f86527 --- /dev/null +++ b/devui/tree/src/composables/use-merge-node.ts @@ -0,0 +1,54 @@ +import { ref } from 'vue'; + +export default function useMergeNode(data: Array): any { + + + const mergeObject = ( + treeItem, + childName = 'children', + labelName = 'label' + ): any => { + const { [childName]: children, [labelName]: label } = treeItem; + if ( + Array.isArray(children) && + children.length === 1 && + children[0][childName] && + children[0][childName].length === 1 + ) { + return mergeObject( + Object.assign({}, children[0], { + [labelName]: `${label} \\ ${children[0][labelName]}`, + }) + ); + } + return treeItem; + }; + + const mergeNode = ( + tree: Array, + level = 0, + childName = 'children', + labelName = 'label' + ): Array => { + return tree.map((item) => { + const { [childName]: children } = item; + if (!Array.isArray(children) || !children.length) { + return Object.assign({}, item, { level: level + 1 }); + } + let currentObject = item; + if (children.length === 1) { + currentObject = mergeObject(item); + } + return Object.assign({}, currentObject, { + [childName]: mergeNode(currentObject[childName], level + 1, childName, labelName), + level: level + 1, + }); + }); + }; + + const mergeData = ref(mergeNode(data)); + + return { + mergeData, + }; +} diff --git a/devui/tree/src/tree.tsx b/devui/tree/src/tree.tsx index 17173f72fd1a340374ad851c4c01b4a577df5f5c..0d7fae875a7f2bb3fe14f82ef15542b46bd4ce04 100644 --- a/devui/tree/src/tree.tsx +++ b/devui/tree/src/tree.tsx @@ -2,6 +2,7 @@ import { defineComponent, toRefs } from 'vue' import { treeProps, TreeProps } from './tree-types' import { flatten } from './util' import useToggle from './composables/use-toggle' +import useMergeNode from './composables/use-merge-node' import useHighlightNode from './composables/use-highlight' import IconOpen from './assets/open.svg' import IconClose from './assets/close.svg' @@ -15,7 +16,9 @@ export default defineComponent({ const { data } = toRefs(props) const flatData = flatten(data.value) - const { openedData, toggle } = useToggle(data.value) + const { mergeData } = useMergeNode(data.value) + + const { openedData, toggle } = useToggle(mergeData.value) const { nodeClassNameReflect, handleInitNodeClassNameReflect, handleClickOnNode } = useHighlightNode() const Indent = () => { diff --git a/docs/components/tree/index.md b/docs/components/tree/index.md index 5b76cc1b562d89dab310596ce3bffa646020270a..f2c350b69f3621f65a0f17cb3c26b670e69cc2f1 100644 --- a/docs/components/tree/index.md +++ b/docs/components/tree/index.md @@ -171,4 +171,103 @@ export default defineComponent({ ::: +### 合并节点 +:::demo 当节点下只有一个子节点时,合并该节点。 + +```vue + + + +``` +::: \ No newline at end of file