refactor: tree-select

pull/4577/head
tangjinzhou 2021-08-22 22:22:22 +08:00
parent 8bf14f40ac
commit 8e38ed883c
10 changed files with 43 additions and 21 deletions

View File

@ -70,6 +70,7 @@ const TreeSelect = defineComponent({
}), }),
slots: [ slots: [
'title', 'title',
'titleRender',
'placeholder', 'placeholder',
'maxTagPlaceholder', 'maxTagPlaceholder',
'treeIcon', 'treeIcon',

View File

@ -42,7 +42,7 @@ export default defineComponent({
showIcon: true, showIcon: true,
expandAction: 'click', expandAction: 'click',
}), }),
slots: ['icon', 'title', 'switcherIcon'], slots: ['icon', 'title', 'switcherIcon', 'titleRender'],
emits: [ emits: [
'update:selectedKeys', 'update:selectedKeys',
'update:checkedKeys', 'update:checkedKeys',

View File

@ -141,7 +141,7 @@ export default defineComponent({
showIcon: false, showIcon: false,
blockNode: false, blockNode: false,
}), }),
slots: ['icon', 'title', 'switcherIcon'], slots: ['icon', 'title', 'switcherIcon', 'titleRender'],
emits: [ emits: [
'update:selectedKeys', 'update:selectedKeys',
'update:checkedKeys', 'update:checkedKeys',

View File

@ -1,7 +1,7 @@
import pickAttrs from '../../_util/pickAttrs'; import pickAttrs from '../../_util/pickAttrs';
import Input from './Input'; import Input from './Input';
import type { InnerSelectorProps } from './interface'; import type { InnerSelectorProps } from './interface';
import type { VNodeChild } from 'vue'; import { Fragment, Suspense, VNodeChild } from 'vue';
import { computed, defineComponent, ref, watch } from 'vue'; import { computed, defineComponent, ref, watch } from 'vue';
import PropTypes from '../../_util/vue-types'; import PropTypes from '../../_util/vue-types';
import { useInjectTreeSelectContext } from 'ant-design-vue/es/vc-tree-select/Context'; import { useInjectTreeSelectContext } from 'ant-design-vue/es/vc-tree-select/Context';
@ -96,11 +96,21 @@ const SingleSelector = defineComponent<SelectorProps>({
onInputCompositionEnd, onInputCompositionEnd,
} = props; } = props;
const item = values[0]; const item = values[0];
let slotTitle = null; let titleNode = null;
if (treeSelectContext.value.slots) { // custom tree-select title by slot
slotTitle = if (item && treeSelectContext.value.slots) {
titleNode =
item.label ||
treeSelectContext.value.slots[item?.option?.data?.slots?.title] || treeSelectContext.value.slots[item?.option?.data?.slots?.title] ||
treeSelectContext.value.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 ( return (
<> <>
@ -134,8 +144,7 @@ const SingleSelector = defineComponent<SelectorProps>({
{/* Display value */} {/* Display value */}
{!combobox.value && item && !hasTextInput.value && ( {!combobox.value && item && !hasTextInput.value && (
<span class={`${prefixCls}-selection-item`} title={title.value}> <span class={`${prefixCls}-selection-item`} title={title.value}>
{/* <Fragment key={item.key || item.value}>{item.label}</Fragment> */} <Fragment key={item.key || item.value}>{titleNode}</Fragment>
{slotTitle?.(item.option?.data) || item.label}
</span> </span>
)} )}

View File

@ -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 { SkipType } from './hooks/useKeyValueMapping';
import type { ComputedRef, InjectionKey, PropType } from 'vue'; import type { ComputedRef, InjectionKey, PropType } from 'vue';
import { computed, defineComponent, inject, provide } from 'vue'; import { computed, defineComponent, inject, provide } from 'vue';
@ -31,7 +37,11 @@ interface ContextProps {
ignoreDisabledCheck?: boolean, ignoreDisabledCheck?: boolean,
) => FlattenDataNode; ) => FlattenDataNode;
slots: Record<string, any>; slots: {
title?: (data: InternalDataEntity) => any;
titleRender?: (data: InternalDataEntity) => any;
[key: string]: (d: any) => any | undefined;
};
} }
const SelectContextKey: InjectionKey<ComputedRef<ContextProps>> = Symbol('SelectContextKey'); const SelectContextKey: InjectionKey<ComputedRef<ContextProps>> = Symbol('SelectContextKey');

View File

@ -34,7 +34,7 @@ import classNames from '../_util/classNames';
export default defineComponent({ export default defineComponent({
name: 'Tree', name: 'Tree',
inheritAttrs: false, inheritAttrs: false,
slots: ['checkable', 'title', 'icon'], slots: ['checkable', 'title', 'icon', 'titleRender'],
props: initDefaultProps(treeProps(), { props: initDefaultProps(treeProps(), {
prefixCls: 'vc-tree', prefixCls: 'vc-tree',
showLine: false, showLine: false,
@ -1023,8 +1023,6 @@ export default defineComponent({
loadData, loadData,
filterTreeNode, filterTreeNode,
titleRender: slots.title,
onNodeClick, onNodeClick,
onNodeDoubleClick, onNodeDoubleClick,
onNodeExpand, onNodeExpand,

View File

@ -362,7 +362,7 @@ export default defineComponent({
icon: treeIcon, icon: treeIcon,
draggable, draggable,
loadData, loadData,
titleRender, slots: contextSlots,
} = context.value; } = context.value;
const disabled = isDisabled.value; const disabled = isDisabled.value;
const mergedDraggable = typeof draggable === 'function' ? draggable(data) : draggable; const mergedDraggable = typeof draggable === 'function' ? draggable(data) : draggable;
@ -390,11 +390,12 @@ export default defineComponent({
let titleNode: any; let titleNode: any;
if (typeof title === 'function') { if (typeof title === 'function') {
titleNode = title(data); titleNode = title(data);
} else if (titleRender) { } else if (contextSlots.titleRender) {
titleNode = titleRender(data); titleNode = contextSlots.titleRender(data);
} else { } else {
titleNode = title === undefined ? defaultTitle : title; titleNode = title;
} }
titleNode = titleNode === undefined ? defaultTitle : titleNode;
const $title = <span class={`${prefixCls}-title`}>{titleNode}</span>; const $title = <span class={`${prefixCls}-title`}>{titleNode}</span>;

View File

@ -64,7 +64,6 @@ export interface TreeContextProps {
loadData: (treeNode: EventDataNode) => Promise<void>; loadData: (treeNode: EventDataNode) => Promise<void>;
filterTreeNode: (treeNode: EventDataNode) => boolean; filterTreeNode: (treeNode: EventDataNode) => boolean;
titleRender?: (node: DataNode) => VueNode;
onNodeClick: NodeMouseEventHandler; onNodeClick: NodeMouseEventHandler;
onNodeDoubleClick: NodeMouseEventHandler; onNodeDoubleClick: NodeMouseEventHandler;
@ -81,7 +80,11 @@ export interface TreeContextProps {
onNodeDragLeave: NodeDragEventHandler; onNodeDragLeave: NodeDragEventHandler;
onNodeDragEnd: NodeDragEventHandler; onNodeDragEnd: NodeDragEventHandler;
onNodeDrop: NodeDragEventHandler; onNodeDrop: NodeDragEventHandler;
slots: Record<string, any>; slots: {
title?: (data: DataNode) => any;
titleRender?: (data: DataNode) => any;
[key: string]: (d: any) => any | undefined;
};
} }
const TreeContextKey: InjectionKey<ComputedRef<TreeContextProps>> = Symbol('TreeContextKey'); const TreeContextKey: InjectionKey<ComputedRef<TreeContextProps>> = Symbol('TreeContextKey');

View File

@ -132,7 +132,7 @@ export const treeProps = () => ({
defaultSelectedKeys: { type: Array as PropType<Key[]> }, defaultSelectedKeys: { type: Array as PropType<Key[]> },
selectedKeys: { type: Array as PropType<Key[]> }, selectedKeys: { type: Array as PropType<Key[]> },
allowDrop: { type: Function as PropType<AllowDrop> }, allowDrop: { type: Function as PropType<AllowDrop> },
// titleRender: { type: Function as PropType<(node: DataNode) => any> },
dropIndicatorRender: { dropIndicatorRender: {
type: Function as PropType< type: Function as PropType<
(props: { (props: {

View File

@ -7,7 +7,7 @@
placeholder="Please select" placeholder="Please select"
tree-default-expand-all tree-default-expand-all
> >
<template #title1="{ key, value }"> <template #title="{ key, value }">
<span v-if="key === '0-0-1'" style="color: #08c">Child Node1 {{ value }}</span> <span v-if="key === '0-0-1'" style="color: #08c">Child Node1 {{ value }}</span>
</template> </template>
</a-tree-select> </a-tree-select>