From e00578c40a585a4a35f235c0228aebaf62cea1ba Mon Sep 17 00:00:00 2001 From: Lan <6995syu@163.com> Date: Mon, 30 Aug 2021 09:04:59 +0800 Subject: [PATCH] =?UTF-8?q?feat(tree):=201.=20=E6=B7=BB=E5=8A=A0=E8=87=AA?= =?UTF-8?q?=E5=AE=9A=E4=B9=89=E6=95=B0=E6=8D=AE=E8=BF=87=E6=BB=A4=E5=88=A4?= =?UTF-8?q?=E6=96=AD=E6=96=B9=E6=B3=95=202.=20=E6=B7=BB=E5=8A=A0=E6=90=9C?= =?UTF-8?q?=E7=B4=A2=E5=AE=8C=E6=88=90=E8=87=AA=E5=8A=A8=E5=B1=95=E5=BC=80?= =?UTF-8?q?=E7=BB=93=E6=9E=9C=E9=80=89=E9=A1=B9=203.=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E6=90=9C=E7=B4=A2=E5=AE=8C=E6=88=90=E8=87=AA=E5=8A=A8=E9=80=89?= =?UTF-8?q?=E4=B8=AD=E7=BB=93=E6=9E=9C=E9=80=89=E9=A1=B9=204.=20=E6=A0=91?= =?UTF-8?q?=E8=8A=82=E7=82=B9=E6=95=B0=E6=8D=AE=E5=8F=98=E5=8C=96=E6=97=B6?= =?UTF-8?q?=E5=BC=BA=E5=88=B6=E6=90=9C=E7=B4=A2(=E5=90=8C=E6=AD=A5searchDa?= =?UTF-8?q?ta=E9=81=BF=E5=85=8D=E5=B1=95=E7=A4=BA=E9=94=99=E8=AF=AF)=20(#1?= =?UTF-8?q?132)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Tree/src/Tree.vue | 21 +++++++++++++++++++-- src/components/Tree/src/props.ts | 20 +++++++++++++++++++- 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/src/components/Tree/src/Tree.vue b/src/components/Tree/src/Tree.vue index 68f97308..d026754e 100644 --- a/src/components/Tree/src/Tree.vue +++ b/src/components/Tree/src/Tree.vue @@ -211,16 +211,32 @@ searchState.startSearch = false; return; } + const { filterFn, checkable, expandOnSearch, checkOnSearch } = unref(props); searchState.startSearch = true; - const { title: titleField } = unref(getReplaceFields); + const { title: titleField, key: keyField } = unref(getReplaceFields); + const searchKeys: string[] = []; searchState.searchData = filter( unref(treeDataRef), (node) => { - return node[titleField]?.includes(searchValue) ?? false; + const result = filterFn + ? filterFn(searchValue, node, unref(getReplaceFields)) + : node[titleField]?.includes(searchValue) ?? false; + if (result) { + searchKeys.push(node[keyField]); + } + return result; }, unref(getReplaceFields), ); + + if (expandOnSearch && searchKeys.length > 0) { + setExpandedKeys(searchKeys); + } + + if (checkOnSearch && checkable && searchKeys.length > 0) { + setCheckedKeys(searchKeys); + } } function handleClickNode(key: string, children: TreeItem[]) { @@ -239,6 +255,7 @@ watchEffect(() => { treeDataRef.value = props.treeData as TreeItem[]; + handleSearch(unref(searchText)); }); onMounted(() => { diff --git a/src/components/Tree/src/props.ts b/src/components/Tree/src/props.ts index 7fb3fce6..287d2f95 100644 --- a/src/components/Tree/src/props.ts +++ b/src/components/Tree/src/props.ts @@ -1,5 +1,12 @@ import type { PropType } from 'vue'; -import type { ReplaceFields, ActionItem, Keys, CheckKeys, ContextMenuOptions } from './typing'; +import type { + ReplaceFields, + ActionItem, + Keys, + CheckKeys, + ContextMenuOptions, + TreeItem, +} from './typing'; import type { ContextMenuItem } from '/@/hooks/web/useContextMenu'; import type { TreeDataItem } from 'ant-design-vue/es/tree/Tree'; import { propTypes } from '/@/utils/propTypes'; @@ -66,6 +73,17 @@ export const basicProps = { rightMenuList: { type: Array as PropType, }, + // 自定义数据过滤判断方法(注: 不是整个过滤方法,而是内置过滤的判断方法,用于增强原本仅能通过title进行过滤的方式) + filterFn: { + type: Function as PropType< + (searchValue: any, node: TreeItem, replaceFields: ReplaceFields) => boolean + >, + default: null, + }, + // 搜索完成时自动展开结果 + expandOnSearch: propTypes.bool.def(false), + // 搜索完成自动选中所有结果,当且仅当 checkable===true 时生效 + checkOnSearch: propTypes.bool.def(false), }; export const treeNodeProps = {