123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211 |
- import type { InsertNodeParams, KeyType, FieldNames, TreeItem } from '../types/tree';
- import type { Ref, ComputedRef } from 'vue';
- import type { TreeDataItem } from 'ant-design-vue/es/tree/Tree';
- import { cloneDeep } from 'lodash-es';
- import { unref } from 'vue';
- import { forEach } from '/@/utils/helper/treeHelper';
- export function useTree(treeDataRef: Ref<TreeDataItem[]>, getFieldNames: ComputedRef<FieldNames>) {
- function getAllKeys(list?: TreeDataItem[]) {
- const keys: string[] = [];
- const treeData = list || unref(treeDataRef);
- const { key: keyField, children: childrenField } = unref(getFieldNames);
- if (!childrenField || !keyField) return keys;
- for (let index = 0; index < treeData.length; index++) {
- const node = treeData[index];
- keys.push(node[keyField]!);
- const children = node[childrenField];
- if (children && children.length) {
- keys.push(...(getAllKeys(children) as string[]));
- }
- }
- return keys as KeyType[];
- }
- // get keys that can be checked and selected
- function getEnabledKeys(list?: TreeDataItem[]) {
- const keys: string[] = [];
- const treeData = list || unref(treeDataRef);
- const { key: keyField, children: childrenField } = unref(getFieldNames);
- if (!childrenField || !keyField) return keys;
- for (let index = 0; index < treeData.length; index++) {
- const node = treeData[index];
- node.disabled !== true && node.selectable !== false && keys.push(node[keyField]!);
- const children = node[childrenField];
- if (children && children.length) {
- keys.push(...(getEnabledKeys(children) as string[]));
- }
- }
- return keys as KeyType[];
- }
- function getChildrenKeys(nodeKey: string | number, list?: TreeDataItem[]) {
- const keys: KeyType[] = [];
- const treeData = list || unref(treeDataRef);
- const { key: keyField, children: childrenField } = unref(getFieldNames);
- if (!childrenField || !keyField) return keys;
- for (let index = 0; index < treeData.length; index++) {
- const node = treeData[index];
- const children = node[childrenField];
- if (nodeKey === node[keyField]) {
- keys.push(node[keyField]!);
- if (children && children.length) {
- keys.push(...(getAllKeys(children) as string[]));
- }
- } else {
- if (children && children.length) {
- keys.push(...getChildrenKeys(nodeKey, children));
- }
- }
- }
- return keys as KeyType[];
- }
- // Update node
- function updateNodeByKey(key: string, node: TreeDataItem, list?: TreeDataItem[]) {
- if (!key) return;
- const treeData = list || unref(treeDataRef);
- const { key: keyField, children: childrenField } = unref(getFieldNames);
- if (!childrenField || !keyField) return;
- for (let index = 0; index < treeData.length; index++) {
- const element: any = treeData[index];
- const children = element[childrenField];
- if (element[keyField] === key) {
- treeData[index] = { ...treeData[index], ...node };
- break;
- } else if (children && children.length) {
- updateNodeByKey(key, node, element[childrenField]);
- }
- }
- }
- // Expand the specified level
- function filterByLevel(level = 1, list?: TreeDataItem[], currentLevel = 1) {
- if (!level) {
- return [];
- }
- const res: (string | number)[] = [];
- const data = list || unref(treeDataRef) || [];
- for (let index = 0; index < data.length; index++) {
- const item = data[index];
- const { key: keyField, children: childrenField } = unref(getFieldNames);
- const key = keyField ? item[keyField] : '';
- const children = childrenField ? item[childrenField] : [];
- res.push(key);
- if (children && children.length && currentLevel < level) {
- currentLevel += 1;
- res.push(...filterByLevel(level, children, currentLevel));
- }
- }
- return res as string[] | number[];
- }
- /**
- * 添加节点
- */
- function insertNodeByKey({ parentKey = null, node, push = 'push' }: InsertNodeParams) {
- const treeData: any = cloneDeep(unref(treeDataRef));
- if (!parentKey) {
- treeData[push](node);
- treeDataRef.value = treeData;
- return;
- }
- const { key: keyField, children: childrenField } = unref(getFieldNames);
- if (!childrenField || !keyField) return;
- forEach(treeData, (treeItem) => {
- if (treeItem[keyField] === parentKey) {
- treeItem[childrenField] = treeItem[childrenField] || [];
- treeItem[childrenField][push](node);
- return true;
- }
- });
- treeDataRef.value = treeData;
- }
- /**
- * 批量添加节点
- */
- function insertNodesByKey({ parentKey = null, list, push = 'push' }: InsertNodeParams) {
- const treeData: any = cloneDeep(unref(treeDataRef));
- if (!list || list.length < 1) {
- return;
- }
- if (!parentKey) {
- for (let i = 0; i < list.length; i++) {
- treeData[push](list[i]);
- }
- treeDataRef.value = treeData;
- return;
- } else {
- const { key: keyField, children: childrenField } = unref(getFieldNames);
- if (!childrenField || !keyField) return;
- forEach(treeData, (treeItem) => {
- if (treeItem[keyField] === parentKey) {
- treeItem[childrenField] = treeItem[childrenField] || [];
- for (let i = 0; i < list.length; i++) {
- treeItem[childrenField][push](list[i]);
- }
- treeDataRef.value = treeData;
- return true;
- }
- });
- }
- }
- // Delete node
- function deleteNodeByKey(key: string, list?: TreeDataItem[]) {
- if (!key) return;
- const treeData = list || unref(treeDataRef);
- const { key: keyField, children: childrenField } = unref(getFieldNames);
- if (!childrenField || !keyField) return;
- for (let index = 0; index < treeData.length; index++) {
- const element: any = treeData[index];
- const children = element[childrenField];
- if (element[keyField] === key) {
- treeData.splice(index, 1);
- break;
- } else if (children && children.length) {
- deleteNodeByKey(key, element[childrenField]);
- }
- }
- }
- // Get selected node
- function getSelectedNode(key: KeyType, list?: TreeItem[], selectedNode?: TreeItem | null) {
- if (!key && key !== 0) return null;
- const treeData = list || unref(treeDataRef);
- const { key: keyField, children: childrenField } = unref(getFieldNames);
- if (!keyField) return;
- treeData.forEach((item) => {
- if (selectedNode?.key || selectedNode?.key === 0) return selectedNode;
- if (item[keyField] === key) {
- selectedNode = item;
- return;
- }
- if (item[childrenField!] && item[childrenField!].length) {
- selectedNode = getSelectedNode(key, item[childrenField!], selectedNode);
- }
- });
- return selectedNode || null;
- }
- return {
- deleteNodeByKey,
- insertNodeByKey,
- insertNodesByKey,
- filterByLevel,
- updateNodeByKey,
- getAllKeys,
- getChildrenKeys,
- getEnabledKeys,
- getSelectedNode,
- };
- }
|