Commit f707541dda78146bda89814ddccbb259d9f5d8a2
1 parent
b06a7ab7
fix(tree): fixed `checkedKeys` with `search` mode
修复搜索状态的切换导致的勾选值可能不正确的问题
Showing
2 changed files
with
39 additions
and
23 deletions
src/components/Tree/src/Tree.vue
@@ -18,8 +18,8 @@ | @@ -18,8 +18,8 @@ | ||
18 | import TreeHeader from './TreeHeader.vue'; | 18 | import TreeHeader from './TreeHeader.vue'; |
19 | import { ScrollContainer } from '/@/components/Container'; | 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 | import { extendSlots, getSlot } from '/@/utils/helper/tsxHelper'; | 23 | import { extendSlots, getSlot } from '/@/utils/helper/tsxHelper'; |
24 | import { filter } from '/@/utils/helper/treeHelper'; | 24 | import { filter } from '/@/utils/helper/treeHelper'; |
25 | 25 | ||
@@ -56,25 +56,6 @@ | @@ -56,25 +56,6 @@ | ||
56 | searchData: [] as TreeItem[], | 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 | const treeDataRef = ref<TreeItem[]>([]); | 59 | const treeDataRef = ref<TreeItem[]>([]); |
79 | 60 | ||
80 | const [createContextMenu] = useContextMenu(); | 61 | const [createContextMenu] = useContextMenu(); |
@@ -109,8 +90,19 @@ | @@ -109,8 +90,19 @@ | ||
109 | emit('update:selectedKeys', v); | 90 | emit('update:selectedKeys', v); |
110 | }, | 91 | }, |
111 | onCheck: (v: CheckKeys, e: CheckEvent) => { | 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 | emit('update:value', rawVal); | 106 | emit('update:value', rawVal); |
115 | emit('check', rawVal, e); | 107 | emit('check', rawVal, e); |
116 | }, | 108 | }, |
@@ -134,6 +126,7 @@ | @@ -134,6 +126,7 @@ | ||
134 | filterByLevel, | 126 | filterByLevel, |
135 | updateNodeByKey, | 127 | updateNodeByKey, |
136 | getAllKeys, | 128 | getAllKeys, |
129 | + getChildrenKeys, | ||
137 | } = useTree(treeDataRef, getReplaceFields); | 130 | } = useTree(treeDataRef, getReplaceFields); |
138 | 131 | ||
139 | function getIcon(params: Recordable, icon?: string) { | 132 | function getIcon(params: Recordable, icon?: string) { |
src/components/Tree/src/useTree.ts
@@ -27,6 +27,28 @@ export function useTree( | @@ -27,6 +27,28 @@ export function useTree( | ||
27 | return keys as Keys; | 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 | // Update node | 52 | // Update node |
31 | function updateNodeByKey(key: string, node: TreeDataItem, list?: TreeDataItem[]) { | 53 | function updateNodeByKey(key: string, node: TreeDataItem, list?: TreeDataItem[]) { |
32 | if (!key) return; | 54 | if (!key) return; |
@@ -146,5 +168,6 @@ export function useTree( | @@ -146,5 +168,6 @@ export function useTree( | ||
146 | filterByLevel, | 168 | filterByLevel, |
147 | updateNodeByKey, | 169 | updateNodeByKey, |
148 | getAllKeys, | 170 | getAllKeys, |
171 | + getChildrenKeys, | ||
149 | }; | 172 | }; |
150 | } | 173 | } |