Commit f707541dda78146bda89814ddccbb259d9f5d8a2

Authored by 无木
1 parent b06a7ab7

fix(tree): fixed `checkedKeys` with `search` mode

修复搜索状态的切换导致的勾选值可能不正确的问题
src/components/Tree/src/Tree.vue
... ... @@ -18,8 +18,8 @@
18 18 import TreeHeader from './TreeHeader.vue';
19 19 import { ScrollContainer } from '/@/components/Container';
20 20  
21   - import { omit, get, cloneDeep, concat, uniq } from 'lodash-es';
22   - import { isBoolean, isFunction } from '/@/utils/is';
  21 + import { omit, get, difference } from 'lodash-es';
  22 + import { isArray, isBoolean, isFunction } from '/@/utils/is';
23 23 import { extendSlots, getSlot } from '/@/utils/helper/tsxHelper';
24 24 import { filter } from '/@/utils/helper/treeHelper';
25 25  
... ... @@ -56,25 +56,6 @@
56 56 searchData: [] as TreeItem[],
57 57 });
58 58  
59   - const copyState = {
60   - checkedKeys: [],
61   - };
62   -
63   - watch(
64   - () => searchState.startSearch,
65   - (newVal, oldVal) => {
66   - if (newVal && !oldVal) {
67   - // before search, save current checkedKeys
68   - copyState.checkedKeys = cloneDeep(state.checkedKeys);
69   - } else if (!newVal && oldVal) {
70   - // after search, restore checkedKeys
71   - state.checkedKeys = uniq(concat(state.checkedKeys, copyState.checkedKeys));
72   - copyState.checkedKeys = [];
73   - }
74   - },
75   - { immediate: true }
76   - );
77   -
78 59 const treeDataRef = ref<TreeItem[]>([]);
79 60  
80 61 const [createContextMenu] = useContextMenu();
... ... @@ -109,8 +90,19 @@
109 90 emit('update:selectedKeys', v);
110 91 },
111 92 onCheck: (v: CheckKeys, e: CheckEvent) => {
112   - state.checkedKeys = v;
113   - const rawVal = toRaw(v);
  93 + let currentValue = toRaw(state.checkedKeys) as Keys;
  94 + if (isArray(currentValue) && searchState.startSearch) {
  95 + const { key } = unref(getReplaceFields);
  96 + currentValue = difference(currentValue, getChildrenKeys(e.node.$attrs.node[key]));
  97 + if (e.checked) {
  98 + currentValue.push(e.node.$attrs.node[key]);
  99 + }
  100 + state.checkedKeys = currentValue;
  101 + } else {
  102 + state.checkedKeys = v;
  103 + }
  104 +
  105 + const rawVal = toRaw(state.checkedKeys);
114 106 emit('update:value', rawVal);
115 107 emit('check', rawVal, e);
116 108 },
... ... @@ -134,6 +126,7 @@
134 126 filterByLevel,
135 127 updateNodeByKey,
136 128 getAllKeys,
  129 + getChildrenKeys,
137 130 } = useTree(treeDataRef, getReplaceFields);
138 131  
139 132 function getIcon(params: Recordable, icon?: string) {
... ...
src/components/Tree/src/useTree.ts
... ... @@ -27,6 +27,28 @@ export function useTree(
27 27 return keys as Keys;
28 28 }
29 29  
  30 + function getChildrenKeys(nodeKey: string | number, list?: TreeDataItem[]): Keys {
  31 + const keys: Keys = [];
  32 + const treeData = list || unref(treeDataRef);
  33 + const { key: keyField, children: childrenField } = unref(getReplaceFields);
  34 + if (!childrenField || !keyField) return keys;
  35 + for (let index = 0; index < treeData.length; index++) {
  36 + const node = treeData[index];
  37 + const children = node[childrenField];
  38 + if (nodeKey === node[keyField]) {
  39 + keys.push(node[keyField]!);
  40 + if (children && children.length) {
  41 + keys.push(...(getAllKeys(children) as string[]));
  42 + }
  43 + } else {
  44 + if (children && children.length) {
  45 + keys.push(...getChildrenKeys(nodeKey, children));
  46 + }
  47 + }
  48 + }
  49 + return keys as Keys;
  50 + }
  51 +
30 52 // Update node
31 53 function updateNodeByKey(key: string, node: TreeDataItem, list?: TreeDataItem[]) {
32 54 if (!key) return;
... ... @@ -146,5 +168,6 @@ export function useTree(
146 168 filterByLevel,
147 169 updateNodeByKey,
148 170 getAllKeys,
  171 + getChildrenKeys,
149 172 };
150 173 }
... ...