From 8e38ed883cd20ba1eb8ea6f196f1dd2df55d7ab3 Mon Sep 17 00:00:00 2001 From: tangjinzhou <415800467@qq.com> Date: Sun, 22 Aug 2021 22:22:22 +0800 Subject: [PATCH] refactor: tree-select --- components/tree-select/index.tsx | 1 + components/tree/DirectoryTree.tsx | 2 +- components/tree/Tree.tsx | 2 +- .../vc-select/Selector/SingleSelector.tsx | 21 +++++++++++++------ components/vc-tree-select/Context.tsx | 14 +++++++++++-- components/vc-tree/Tree.tsx | 4 +--- components/vc-tree/TreeNode.tsx | 9 ++++---- components/vc-tree/contextTypes.ts | 7 +++++-- components/vc-tree/props.ts | 2 +- examples/App.vue | 2 +- 10 files changed, 43 insertions(+), 21 deletions(-) diff --git a/components/tree-select/index.tsx b/components/tree-select/index.tsx index 1b126c947..c957affd1 100644 --- a/components/tree-select/index.tsx +++ b/components/tree-select/index.tsx @@ -70,6 +70,7 @@ const TreeSelect = defineComponent({ }), slots: [ 'title', + 'titleRender', 'placeholder', 'maxTagPlaceholder', 'treeIcon', diff --git a/components/tree/DirectoryTree.tsx b/components/tree/DirectoryTree.tsx index 113af9198..6a3b319c8 100644 --- a/components/tree/DirectoryTree.tsx +++ b/components/tree/DirectoryTree.tsx @@ -42,7 +42,7 @@ export default defineComponent({ showIcon: true, expandAction: 'click', }), - slots: ['icon', 'title', 'switcherIcon'], + slots: ['icon', 'title', 'switcherIcon', 'titleRender'], emits: [ 'update:selectedKeys', 'update:checkedKeys', diff --git a/components/tree/Tree.tsx b/components/tree/Tree.tsx index b0e0ebde0..7ad82b765 100644 --- a/components/tree/Tree.tsx +++ b/components/tree/Tree.tsx @@ -141,7 +141,7 @@ export default defineComponent({ showIcon: false, blockNode: false, }), - slots: ['icon', 'title', 'switcherIcon'], + slots: ['icon', 'title', 'switcherIcon', 'titleRender'], emits: [ 'update:selectedKeys', 'update:checkedKeys', diff --git a/components/vc-select/Selector/SingleSelector.tsx b/components/vc-select/Selector/SingleSelector.tsx index b83dae774..1b9cbca2f 100644 --- a/components/vc-select/Selector/SingleSelector.tsx +++ b/components/vc-select/Selector/SingleSelector.tsx @@ -1,7 +1,7 @@ import pickAttrs from '../../_util/pickAttrs'; import Input from './Input'; import type { InnerSelectorProps } from './interface'; -import type { VNodeChild } from 'vue'; +import { Fragment, Suspense, VNodeChild } from 'vue'; import { computed, defineComponent, ref, watch } from 'vue'; import PropTypes from '../../_util/vue-types'; import { useInjectTreeSelectContext } from 'ant-design-vue/es/vc-tree-select/Context'; @@ -96,11 +96,21 @@ const SingleSelector = defineComponent({ onInputCompositionEnd, } = props; const item = values[0]; - let slotTitle = null; - if (treeSelectContext.value.slots) { - slotTitle = + let titleNode = null; + // custom tree-select title by slot + if (item && treeSelectContext.value.slots) { + titleNode = + item.label || treeSelectContext.value.slots[item?.option?.data?.slots?.title] || treeSelectContext.value.slots.title; + if (typeof titleNode === 'function') { + titleNode = titleNode(item.option?.data || {}); + } else if (treeSelectContext.value.slots.titleRender) { + // 因历史 title 是覆盖逻辑,新增 titleRender,所有的 title 都走一遍 titleRender + titleNode = treeSelectContext.value.slots.titleRender(item.option?.data || {}); + } + } else { + titleNode = item?.label; } return ( <> @@ -134,8 +144,7 @@ const SingleSelector = defineComponent({ {/* Display value */} {!combobox.value && item && !hasTextInput.value && ( - {/* {item.label} */} - {slotTitle?.(item.option?.data) || item.label} + {titleNode} )} diff --git a/components/vc-tree-select/Context.tsx b/components/vc-tree-select/Context.tsx index a84a09e25..9b7b8d8e7 100644 --- a/components/vc-tree-select/Context.tsx +++ b/components/vc-tree-select/Context.tsx @@ -1,4 +1,10 @@ -import type { FlattenDataNode, Key, LegacyDataNode, RawValueType } from './interface'; +import type { + FlattenDataNode, + InternalDataEntity, + Key, + LegacyDataNode, + RawValueType, +} from './interface'; import type { SkipType } from './hooks/useKeyValueMapping'; import type { ComputedRef, InjectionKey, PropType } from 'vue'; import { computed, defineComponent, inject, provide } from 'vue'; @@ -31,7 +37,11 @@ interface ContextProps { ignoreDisabledCheck?: boolean, ) => FlattenDataNode; - slots: Record; + slots: { + title?: (data: InternalDataEntity) => any; + titleRender?: (data: InternalDataEntity) => any; + [key: string]: (d: any) => any | undefined; + }; } const SelectContextKey: InjectionKey> = Symbol('SelectContextKey'); diff --git a/components/vc-tree/Tree.tsx b/components/vc-tree/Tree.tsx index 2553bcd5b..2abfbc171 100644 --- a/components/vc-tree/Tree.tsx +++ b/components/vc-tree/Tree.tsx @@ -34,7 +34,7 @@ import classNames from '../_util/classNames'; export default defineComponent({ name: 'Tree', inheritAttrs: false, - slots: ['checkable', 'title', 'icon'], + slots: ['checkable', 'title', 'icon', 'titleRender'], props: initDefaultProps(treeProps(), { prefixCls: 'vc-tree', showLine: false, @@ -1023,8 +1023,6 @@ export default defineComponent({ loadData, filterTreeNode, - titleRender: slots.title, - onNodeClick, onNodeDoubleClick, onNodeExpand, diff --git a/components/vc-tree/TreeNode.tsx b/components/vc-tree/TreeNode.tsx index aa8cb0637..4ce63c536 100644 --- a/components/vc-tree/TreeNode.tsx +++ b/components/vc-tree/TreeNode.tsx @@ -362,7 +362,7 @@ export default defineComponent({ icon: treeIcon, draggable, loadData, - titleRender, + slots: contextSlots, } = context.value; const disabled = isDisabled.value; const mergedDraggable = typeof draggable === 'function' ? draggable(data) : draggable; @@ -390,11 +390,12 @@ export default defineComponent({ let titleNode: any; if (typeof title === 'function') { titleNode = title(data); - } else if (titleRender) { - titleNode = titleRender(data); + } else if (contextSlots.titleRender) { + titleNode = contextSlots.titleRender(data); } else { - titleNode = title === undefined ? defaultTitle : title; + titleNode = title; } + titleNode = titleNode === undefined ? defaultTitle : titleNode; const $title = {titleNode}; diff --git a/components/vc-tree/contextTypes.ts b/components/vc-tree/contextTypes.ts index 80b118163..24c4d1a40 100644 --- a/components/vc-tree/contextTypes.ts +++ b/components/vc-tree/contextTypes.ts @@ -64,7 +64,6 @@ export interface TreeContextProps { loadData: (treeNode: EventDataNode) => Promise; filterTreeNode: (treeNode: EventDataNode) => boolean; - titleRender?: (node: DataNode) => VueNode; onNodeClick: NodeMouseEventHandler; onNodeDoubleClick: NodeMouseEventHandler; @@ -81,7 +80,11 @@ export interface TreeContextProps { onNodeDragLeave: NodeDragEventHandler; onNodeDragEnd: NodeDragEventHandler; onNodeDrop: NodeDragEventHandler; - slots: Record; + slots: { + title?: (data: DataNode) => any; + titleRender?: (data: DataNode) => any; + [key: string]: (d: any) => any | undefined; + }; } const TreeContextKey: InjectionKey> = Symbol('TreeContextKey'); diff --git a/components/vc-tree/props.ts b/components/vc-tree/props.ts index ecce7f459..7bc9451f5 100644 --- a/components/vc-tree/props.ts +++ b/components/vc-tree/props.ts @@ -132,7 +132,7 @@ export const treeProps = () => ({ defaultSelectedKeys: { type: Array as PropType }, selectedKeys: { type: Array as PropType }, allowDrop: { type: Function as PropType }, - // titleRender: { type: Function as PropType<(node: DataNode) => any> }, + dropIndicatorRender: { type: Function as PropType< (props: { diff --git a/examples/App.vue b/examples/App.vue index b85bf8e8e..7aad99ccf 100644 --- a/examples/App.vue +++ b/examples/App.vue @@ -7,7 +7,7 @@ placeholder="Please select" tree-default-expand-all > -