vben
2021-11-24 413df9f5e1652307399f14249b688c076e886603
提交 | 用户 | age
3f6920 1 import type { InsertNodeParams, Keys, ReplaceFields } from './typing';
e8ccdc 2 import type { Ref, ComputedRef } from 'vue';
72b42d 3 import type { TreeDataItem } from 'ant-design-vue/es/tree/Tree';
e8ccdc 4
V 5 import { cloneDeep } from 'lodash-es';
6 import { unref } from 'vue';
7 import { forEach } from '/@/utils/helper/treeHelper';
8
9 export function useTree(
72b42d 10   treeDataRef: Ref<TreeDataItem[]>,
56a966 11   getReplaceFields: ComputedRef<ReplaceFields>,
e8ccdc 12 ) {
cd8e92 13   function getAllKeys(list?: TreeDataItem[]) {
V 14     const keys: string[] = [];
15     const treeData = list || unref(treeDataRef);
16     const { key: keyField, children: childrenField } = unref(getReplaceFields);
17     if (!childrenField || !keyField) return keys;
18
19     for (let index = 0; index < treeData.length; index++) {
20       const node = treeData[index];
21       keys.push(node[keyField]!);
22       const children = node[childrenField];
23       if (children && children.length) {
24         keys.push(...(getAllKeys(children) as string[]));
25       }
26     }
27     return keys as Keys;
28   }
3fcfac 29
ddd189 30   // get keys that can be checked and selected
31   function getEnabledKeys(list?: TreeDataItem[]) {
32     const keys: string[] = [];
33     const treeData = list || unref(treeDataRef);
34     const { key: keyField, children: childrenField } = unref(getReplaceFields);
35     if (!childrenField || !keyField) return keys;
36
37     for (let index = 0; index < treeData.length; index++) {
38       const node = treeData[index];
39       node.disabled !== true && node.selectable !== false && keys.push(node[keyField]!);
40       const children = node[childrenField];
41       if (children && children.length) {
42         keys.push(...(getEnabledKeys(children) as string[]));
43       }
44     }
45     return keys as Keys;
46   }
cd8e92 47
f70754 48   function getChildrenKeys(nodeKey: string | number, list?: TreeDataItem[]): Keys {
49     const keys: Keys = [];
50     const treeData = list || unref(treeDataRef);
51     const { key: keyField, children: childrenField } = unref(getReplaceFields);
52     if (!childrenField || !keyField) return keys;
53     for (let index = 0; index < treeData.length; index++) {
54       const node = treeData[index];
55       const children = node[childrenField];
56       if (nodeKey === node[keyField]) {
57         keys.push(node[keyField]!);
58         if (children && children.length) {
59           keys.push(...(getAllKeys(children) as string[]));
60         }
61       } else {
62         if (children && children.length) {
63           keys.push(...getChildrenKeys(nodeKey, children));
64         }
65       }
66     }
67     return keys as Keys;
68   }
69
72b42d 70   // Update node
V 71   function updateNodeByKey(key: string, node: TreeDataItem, list?: TreeDataItem[]) {
e8ccdc 72     if (!key) return;
V 73     const treeData = list || unref(treeDataRef);
74     const { key: keyField, children: childrenField } = unref(getReplaceFields);
75
76     if (!childrenField || !keyField) return;
77
78     for (let index = 0; index < treeData.length; index++) {
79       const element: any = treeData[index];
80       const children = element[childrenField];
81
82       if (element[keyField] === key) {
83         treeData[index] = { ...treeData[index], ...node };
84         break;
85       } else if (children && children.length) {
86         updateNodeByKey(key, node, element[childrenField]);
87       }
88     }
89   }
90
72b42d 91   // Expand the specified level
V 92   function filterByLevel(level = 1, list?: TreeDataItem[], currentLevel = 1) {
e8ccdc 93     if (!level) {
V 94       return [];
95     }
96     const res: (string | number)[] = [];
97     const data = list || unref(treeDataRef) || [];
98     for (let index = 0; index < data.length; index++) {
f79cae 99       const item = data[index];
e8ccdc 100
V 101       const { key: keyField, children: childrenField } = unref(getReplaceFields);
102       const key = keyField ? item[keyField] : '';
103       const children = childrenField ? item[childrenField] : [];
104       res.push(key);
105       if (children && children.length && currentLevel < level) {
106         currentLevel += 1;
107         res.push(...filterByLevel(level, children, currentLevel));
108       }
109     }
110     return res as string[] | number[];
111   }
112
113   /**
114    * 添加节点
115    */
116   function insertNodeByKey({ parentKey = null, node, push = 'push' }: InsertNodeParams) {
117     const treeData: any = cloneDeep(unref(treeDataRef));
118     if (!parentKey) {
119       treeData[push](node);
120       treeDataRef.value = treeData;
121       return;
122     }
123     const { key: keyField, children: childrenField } = unref(getReplaceFields);
124     if (!childrenField || !keyField) return;
125
126     forEach(treeData, (treeItem) => {
127       if (treeItem[keyField] === parentKey) {
128         treeItem[childrenField] = treeItem[childrenField] || [];
129         treeItem[childrenField][push](node);
d97aa9 130         return true;
e8ccdc 131       }
V 132     });
133     treeDataRef.value = treeData;
134   }
d97aa9 135   /**
B 136    * 批量添加节点
137    */
138   function insertNodesByKey({ parentKey = null, list, push = 'push' }: InsertNodeParams) {
139     const treeData: any = cloneDeep(unref(treeDataRef));
140     if (!list || list.length < 1) {
141       return;
142     }
143     if (!parentKey) {
144       for (let i = 0; i < list.length; i++) {
145         treeData[push](list[i]);
146       }
147     } else {
148       const { key: keyField, children: childrenField } = unref(getReplaceFields);
149       if (!childrenField || !keyField) return;
e8ccdc 150
d97aa9 151       forEach(treeData, (treeItem) => {
B 152         if (treeItem[keyField] === parentKey) {
153           treeItem[childrenField] = treeItem[childrenField] || [];
154           for (let i = 0; i < list.length; i++) {
155             treeItem[childrenField][push](list[i]);
156           }
157           treeDataRef.value = treeData;
158           return true;
159         }
160       });
161     }
162   }
72b42d 163   // Delete node
V 164   function deleteNodeByKey(key: string, list?: TreeDataItem[]) {
e8ccdc 165     if (!key) return;
V 166     const treeData = list || unref(treeDataRef);
167     const { key: keyField, children: childrenField } = unref(getReplaceFields);
168     if (!childrenField || !keyField) return;
169
170     for (let index = 0; index < treeData.length; index++) {
171       const element: any = treeData[index];
172       const children = element[childrenField];
173
174       if (element[keyField] === key) {
175         treeData.splice(index, 1);
176         break;
177       } else if (children && children.length) {
178         deleteNodeByKey(key, element[childrenField]);
179       }
180     }
181   }
d97aa9 182   return {
B 183     deleteNodeByKey,
184     insertNodeByKey,
185     insertNodesByKey,
186     filterByLevel,
187     updateNodeByKey,
188     getAllKeys,
f70754 189     getChildrenKeys,
ddd189 190     getEnabledKeys,
d97aa9 191   };
e8ccdc 192 }