refactor: tree-select
parent
8bf14f40ac
commit
8e38ed883c
|
@ -70,6 +70,7 @@ const TreeSelect = defineComponent({
|
||||||
}),
|
}),
|
||||||
slots: [
|
slots: [
|
||||||
'title',
|
'title',
|
||||||
|
'titleRender',
|
||||||
'placeholder',
|
'placeholder',
|
||||||
'maxTagPlaceholder',
|
'maxTagPlaceholder',
|
||||||
'treeIcon',
|
'treeIcon',
|
||||||
|
|
|
@ -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',
|
||||||
|
|
|
@ -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',
|
||||||
|
|
|
@ -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>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|
|
@ -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');
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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>;
|
||||||
|
|
||||||
|
|
|
@ -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');
|
||||||
|
|
||||||
|
|
|
@ -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: {
|
||||||
|
|
|
@ -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>
|
||||||
|
|
Loading…
Reference in New Issue