From f707541dda78146bda89814ddccbb259d9f5d8a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=97=A0=E6=9C=A8?= Date: Fri, 16 Jul 2021 10:56:37 +0800 Subject: [PATCH] fix(tree): fixed `checkedKeys` with `search` mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修复搜索状态的切换导致的勾选值可能不正确的问题 --- src/components/Tree/src/Tree.vue | 39 ++++++++++++------------------ src/components/Tree/src/useTree.ts | 23 ++++++++++++++++++ 2 files changed, 39 insertions(+), 23 deletions(-) diff --git a/src/components/Tree/src/Tree.vue b/src/components/Tree/src/Tree.vue index 5d7c962d..354dccdf 100644 --- a/src/components/Tree/src/Tree.vue +++ b/src/components/Tree/src/Tree.vue @@ -18,8 +18,8 @@ import TreeHeader from './TreeHeader.vue'; import { ScrollContainer } from '/@/components/Container'; - import { omit, get, cloneDeep, concat, uniq } from 'lodash-es'; - import { isBoolean, isFunction } from '/@/utils/is'; + import { omit, get, difference } from 'lodash-es'; + import { isArray, isBoolean, isFunction } from '/@/utils/is'; import { extendSlots, getSlot } from '/@/utils/helper/tsxHelper'; import { filter } from '/@/utils/helper/treeHelper'; @@ -56,25 +56,6 @@ searchData: [] as TreeItem[], }); - const copyState = { - checkedKeys: [], - }; - - watch( - () => searchState.startSearch, - (newVal, oldVal) => { - if (newVal && !oldVal) { - // before search, save current checkedKeys - copyState.checkedKeys = cloneDeep(state.checkedKeys); - } else if (!newVal && oldVal) { - // after search, restore checkedKeys - state.checkedKeys = uniq(concat(state.checkedKeys, copyState.checkedKeys)); - copyState.checkedKeys = []; - } - }, - { immediate: true } - ); - const treeDataRef = ref([]); const [createContextMenu] = useContextMenu(); @@ -109,8 +90,19 @@ emit('update:selectedKeys', v); }, onCheck: (v: CheckKeys, e: CheckEvent) => { - state.checkedKeys = v; - const rawVal = toRaw(v); + let currentValue = toRaw(state.checkedKeys) as Keys; + if (isArray(currentValue) && searchState.startSearch) { + const { key } = unref(getReplaceFields); + currentValue = difference(currentValue, getChildrenKeys(e.node.$attrs.node[key])); + if (e.checked) { + currentValue.push(e.node.$attrs.node[key]); + } + state.checkedKeys = currentValue; + } else { + state.checkedKeys = v; + } + + const rawVal = toRaw(state.checkedKeys); emit('update:value', rawVal); emit('check', rawVal, e); }, @@ -134,6 +126,7 @@ filterByLevel, updateNodeByKey, getAllKeys, + getChildrenKeys, } = useTree(treeDataRef, getReplaceFields); function getIcon(params: Recordable, icon?: string) { diff --git a/src/components/Tree/src/useTree.ts b/src/components/Tree/src/useTree.ts index d39d5f72..2f03acae 100644 --- a/src/components/Tree/src/useTree.ts +++ b/src/components/Tree/src/useTree.ts @@ -27,6 +27,28 @@ export function useTree( return keys as Keys; } + function getChildrenKeys(nodeKey: string | number, list?: TreeDataItem[]): Keys { + const keys: Keys = []; + const treeData = list || unref(treeDataRef); + const { key: keyField, children: childrenField } = unref(getReplaceFields); + 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 Keys; + } + // Update node function updateNodeByKey(key: string, node: TreeDataItem, list?: TreeDataItem[]) { if (!key) return; @@ -146,5 +168,6 @@ export function useTree( filterByLevel, updateNodeByKey, getAllKeys, + getChildrenKeys, }; } -- GitLab