refactor: tree-select
parent
81c16aba93
commit
8bf14f40ac
|
@ -1,6 +1,6 @@
|
|||
import type { App, Plugin, VNode, ExtractPropTypes } from 'vue';
|
||||
import { defineComponent, inject, provide } from 'vue';
|
||||
import Select, { SelectProps } from '../select';
|
||||
import Select, { selectProps } from '../select';
|
||||
import Input from '../input';
|
||||
import PropTypes from '../_util/vue-types';
|
||||
import { defaultConfigProvider } from '../config-provider';
|
||||
|
@ -15,7 +15,7 @@ function isSelectOptionOrSelectOptGroup(child: any): boolean {
|
|||
}
|
||||
|
||||
const autoCompleteProps = {
|
||||
...SelectProps(),
|
||||
...selectProps(),
|
||||
dataSource: PropTypes.array,
|
||||
dropdownMenuStyle: PropTypes.style,
|
||||
optionLabelProp: PropTypes.string,
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import { defineComponent } from 'vue';
|
||||
import VcSelect, { SelectProps } from '../select';
|
||||
import VcSelect, { selectProps } from '../select';
|
||||
import { getOptionProps, getSlot } from '../_util/props-util';
|
||||
|
||||
export default defineComponent({
|
||||
inheritAttrs: false,
|
||||
props: SelectProps(),
|
||||
props: selectProps(),
|
||||
Option: VcSelect.Option,
|
||||
render() {
|
||||
const selectOptionsProps = getOptionProps(this);
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import type { App, PropType, Plugin, ExtractPropTypes } from 'vue';
|
||||
import { computed, defineComponent, ref } from 'vue';
|
||||
import omit from 'omit.js';
|
||||
import classNames from '../_util/classNames';
|
||||
import type { SelectProps as RcSelectProps } from '../vc-select';
|
||||
import { selectProps as vcSelectProps } from '../vc-select';
|
||||
import RcSelect, { Option, OptGroup, selectBaseProps } from '../vc-select';
|
||||
import type { OptionProps as OptionPropsType } from '../vc-select/Option';
|
||||
import getIcons from './utils/iconUtil';
|
||||
|
@ -10,6 +9,7 @@ import PropTypes from '../_util/vue-types';
|
|||
import { tuple } from '../_util/type';
|
||||
import useConfigInject from '../_util/hooks/useConfigInject';
|
||||
import type { SizeType } from '../config-provider';
|
||||
import omit from '../_util/omit';
|
||||
|
||||
type RawValue = string | number;
|
||||
|
||||
|
@ -24,24 +24,8 @@ export interface LabeledValue {
|
|||
}
|
||||
export type SelectValue = RawValue | RawValue[] | LabeledValue | LabeledValue[] | undefined;
|
||||
|
||||
interface InternalSelectProps<VT> extends Omit<RcSelectProps<VT>, 'mode'> {
|
||||
suffixIcon?: any;
|
||||
itemIcon?: any;
|
||||
size?: SizeType;
|
||||
mode?: 'multiple' | 'tags' | 'SECRET_COMBOBOX_MODE_DO_NOT_USE';
|
||||
bordered?: boolean;
|
||||
}
|
||||
|
||||
interface SelectPropsTypes<VT>
|
||||
extends Omit<InternalSelectProps<VT>, 'inputIcon' | 'mode' | 'getInputElement' | 'backfill'> {
|
||||
mode?: 'multiple' | 'tags';
|
||||
}
|
||||
export type SelectProps = Partial<ExtractPropTypes<SelectPropsTypes<SelectValue>>>;
|
||||
export const selectProps = () => ({
|
||||
...(omit(selectBaseProps(), ['inputIcon', 'mode', 'getInputElement', 'backfill']) as Omit<
|
||||
SelectPropsTypes<SelectValue>,
|
||||
'inputIcon' | 'mode' | 'getInputElement' | 'backfill' | 'class' | 'style'
|
||||
>),
|
||||
...omit(vcSelectProps<SelectValue>(), ['inputIcon', 'mode', 'getInputElement', 'backfill']),
|
||||
value: {
|
||||
type: [Array, Object, String, Number] as PropType<SelectValue>,
|
||||
},
|
||||
|
@ -58,6 +42,8 @@ export const selectProps = () => ({
|
|||
choiceTransitionName: PropTypes.string.def(''),
|
||||
});
|
||||
|
||||
export type SelectProps = Partial<ExtractPropTypes<ReturnType<typeof selectProps>>>;
|
||||
|
||||
const Select = defineComponent({
|
||||
name: 'ASelect',
|
||||
Option,
|
||||
|
|
|
@ -11,8 +11,6 @@ import VcTreeSelect, {
|
|||
import classNames from '../_util/classNames';
|
||||
import initDefaultProps from '../_util/props-util/initDefaultProps';
|
||||
import type { SizeType } from '../config-provider';
|
||||
|
||||
export { TreeData, TreeSelectProps } from './interface';
|
||||
import LoadingOutlined from '@ant-design/icons-vue/LoadingOutlined';
|
||||
import CaretDownOutlined from '@ant-design/icons-vue/CaretDownOutlined';
|
||||
import type { DefaultValueType, FieldNames } from '../vc-tree-select/interface';
|
||||
|
@ -23,6 +21,7 @@ import devWarning from '../vc-util/devWarning';
|
|||
import getIcons from '../select/utils/iconUtil';
|
||||
import renderSwitcherIcon from '../tree/utils/iconUtil';
|
||||
import type { AntTreeNodeProps } from '../tree/Tree';
|
||||
import { warning } from '../vc-util/warning';
|
||||
|
||||
const getTransitionName = (rootPrefixCls: string, motion: string, transitionName?: string) => {
|
||||
if (transitionName !== undefined) {
|
||||
|
@ -53,6 +52,7 @@ export const treeSelectProps = {
|
|||
replaceFields: { type: Object as PropType<FieldNames> },
|
||||
};
|
||||
export type TreeSelectProps = Partial<ExtractPropTypes<typeof treeSelectProps>>;
|
||||
|
||||
const TreeSelect = defineComponent({
|
||||
TreeNode,
|
||||
SHOW_ALL,
|
||||
|
@ -68,8 +68,19 @@ const TreeSelect = defineComponent({
|
|||
listItemHeight: 26,
|
||||
bordered: true,
|
||||
}),
|
||||
slots: ['placeholder', 'maxTagPlaceholder', 'treeIcon', 'switcherIcon', 'notFoundContent'],
|
||||
slots: [
|
||||
'title',
|
||||
'placeholder',
|
||||
'maxTagPlaceholder',
|
||||
'treeIcon',
|
||||
'switcherIcon',
|
||||
'notFoundContent',
|
||||
],
|
||||
setup(props, { attrs, slots, expose, emit }) {
|
||||
warning(
|
||||
!(props.treeData === undefined && slots.default),
|
||||
'`children` of Tree is deprecated. Please use `treeData` instead.',
|
||||
);
|
||||
watchEffect(() => {
|
||||
devWarning(
|
||||
props.multiple !== false || !props.treeCheckable,
|
||||
|
@ -212,6 +223,7 @@ const TreeSelect = defineComponent({
|
|||
onSearch={handleSearch}
|
||||
onTreeExpand={handleTreeExpand}
|
||||
v-slots={{
|
||||
...slots,
|
||||
treeCheckable: () => <span class={`${prefixCls.value}-tree-checkbox-inner`} />,
|
||||
}}
|
||||
children={slots.default?.()}
|
||||
|
|
|
@ -1,65 +0,0 @@
|
|||
import PropTypes, { withUndefined } from '../_util/vue-types';
|
||||
import { SelectProps } from '../select';
|
||||
import { tuple } from '../_util/type';
|
||||
|
||||
export const TreeData = PropTypes.shape({
|
||||
key: PropTypes.string,
|
||||
value: PropTypes.string,
|
||||
label: PropTypes.VNodeChild,
|
||||
slots: PropTypes.object,
|
||||
children: PropTypes.array,
|
||||
}).loose;
|
||||
|
||||
export const TreeSelectProps = () => ({
|
||||
...SelectProps(),
|
||||
autofocus: PropTypes.looseBool,
|
||||
dropdownStyle: PropTypes.object,
|
||||
filterTreeNode: withUndefined(PropTypes.oneOfType([Function, Boolean])),
|
||||
getPopupContainer: PropTypes.func,
|
||||
labelInValue: PropTypes.looseBool,
|
||||
loadData: PropTypes.func,
|
||||
maxTagCount: PropTypes.number,
|
||||
maxTagPlaceholder: PropTypes.VNodeChild,
|
||||
value: PropTypes.oneOfType([
|
||||
PropTypes.string,
|
||||
PropTypes.object,
|
||||
PropTypes.array,
|
||||
PropTypes.number,
|
||||
]),
|
||||
defaultValue: PropTypes.oneOfType([
|
||||
PropTypes.string,
|
||||
PropTypes.object,
|
||||
PropTypes.array,
|
||||
PropTypes.number,
|
||||
]),
|
||||
multiple: PropTypes.looseBool,
|
||||
notFoundContent: PropTypes.VNodeChild,
|
||||
searchPlaceholder: PropTypes.string,
|
||||
searchValue: PropTypes.string,
|
||||
showCheckedStrategy: PropTypes.oneOf(tuple('SHOW_ALL', 'SHOW_PARENT', 'SHOW_CHILD')),
|
||||
suffixIcon: PropTypes.VNodeChild,
|
||||
treeCheckable: PropTypes.looseBool,
|
||||
treeCheckStrictly: PropTypes.looseBool,
|
||||
treeData: PropTypes.arrayOf(Object),
|
||||
treeDataSimpleMode: withUndefined(PropTypes.oneOfType([PropTypes.looseBool, Object])),
|
||||
|
||||
dropdownClassName: PropTypes.string,
|
||||
dropdownMatchSelectWidth: PropTypes.looseBool,
|
||||
treeDefaultExpandAll: PropTypes.looseBool,
|
||||
treeExpandedKeys: PropTypes.array,
|
||||
treeIcon: PropTypes.looseBool,
|
||||
treeDefaultExpandedKeys: PropTypes.array,
|
||||
treeNodeFilterProp: PropTypes.string,
|
||||
treeNodeLabelProp: PropTypes.string,
|
||||
replaceFields: PropTypes.object.def({}),
|
||||
clearIcon: PropTypes.VNodeChild,
|
||||
removeIcon: PropTypes.VNodeChild,
|
||||
|
||||
onSelect: PropTypes.func,
|
||||
onChange: PropTypes.func,
|
||||
onSearch: PropTypes.func,
|
||||
onTreeExpand: PropTypes.func,
|
||||
'onUpdate:treeExpandedKeys': PropTypes.func,
|
||||
'onUpdate:searchValue': PropTypes.func,
|
||||
'onUpdate:value': PropTypes.func,
|
||||
});
|
|
@ -13,6 +13,7 @@ import useConfigInject from '../_util/hooks/useConfigInject';
|
|||
import renderSwitcherIcon from './utils/iconUtil';
|
||||
import dropIndicatorRender from './utils/dropIndicator';
|
||||
import devWarning from '../vc-util/devWarning';
|
||||
import { warning } from '../vc-util/warning';
|
||||
|
||||
export interface AntdTreeNodeAttribute {
|
||||
eventKey: string;
|
||||
|
@ -153,6 +154,10 @@ export default defineComponent({
|
|||
],
|
||||
TreeNode,
|
||||
setup(props, { attrs, expose, emit, slots }) {
|
||||
warning(
|
||||
!(props.treeData === undefined && slots.default),
|
||||
'`children` of Tree is deprecated. Please use `treeData` instead.',
|
||||
);
|
||||
const { prefixCls, direction, virtual } = useConfigInject('tree', props);
|
||||
const treeRef = ref();
|
||||
expose({
|
||||
|
|
|
@ -42,7 +42,7 @@ import {
|
|||
flattenOptions,
|
||||
fillOptionsWithMissingValue,
|
||||
} from './utils/valueUtil';
|
||||
import type { SelectProps } from './generate';
|
||||
import { selectBaseProps, SelectProps } from './generate';
|
||||
import generateSelector from './generate';
|
||||
import type { DefaultValueType } from './interface/generator';
|
||||
import warningProps from './utils/warningPropsUtil';
|
||||
|
@ -68,6 +68,10 @@ export type ExportedSelectProps<T extends DefaultValueType = DefaultValueType> =
|
|||
T
|
||||
>;
|
||||
|
||||
export function selectProps<T>() {
|
||||
return selectBaseProps<SelectOptionsType[number], T>();
|
||||
}
|
||||
|
||||
const Select = defineComponent({
|
||||
name: 'Select',
|
||||
inheritAttrs: false,
|
||||
|
|
|
@ -2,8 +2,9 @@ import pickAttrs from '../../_util/pickAttrs';
|
|||
import Input from './Input';
|
||||
import type { InnerSelectorProps } from './interface';
|
||||
import type { VNodeChild } from 'vue';
|
||||
import { computed, defineComponent, Fragment, ref, watch } 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';
|
||||
|
||||
interface SelectorProps extends InnerSelectorProps {
|
||||
inputElement: VNodeChild;
|
||||
|
@ -50,6 +51,7 @@ const SingleSelector = defineComponent<SelectorProps>({
|
|||
}
|
||||
return inputValue;
|
||||
});
|
||||
const treeSelectContext = useInjectTreeSelectContext();
|
||||
watch(
|
||||
[combobox, () => props.activeValue],
|
||||
() => {
|
||||
|
@ -94,6 +96,12 @@ const SingleSelector = defineComponent<SelectorProps>({
|
|||
onInputCompositionEnd,
|
||||
} = props;
|
||||
const item = values[0];
|
||||
let slotTitle = null;
|
||||
if (treeSelectContext.value.slots) {
|
||||
slotTitle =
|
||||
treeSelectContext.value.slots[item?.option?.data?.slots?.title] ||
|
||||
treeSelectContext.value.slots.title;
|
||||
}
|
||||
return (
|
||||
<>
|
||||
<span class={`${prefixCls}-selection-search`}>
|
||||
|
@ -126,7 +134,8 @@ const SingleSelector = defineComponent<SelectorProps>({
|
|||
{/* Display value */}
|
||||
{!combobox.value && item && !hasTextInput.value && (
|
||||
<span class={`${prefixCls}-selection-item`} title={title.value}>
|
||||
<Fragment key={item.key || item.value}>{item.label}</Fragment>
|
||||
{/* <Fragment key={item.key || item.value}>{item.label}</Fragment> */}
|
||||
{slotTitle?.(item.option?.data) || item.label}
|
||||
</span>
|
||||
)}
|
||||
|
||||
|
|
|
@ -119,7 +119,7 @@ export function selectBaseProps<OptionType, ValueType>() {
|
|||
defaultOpen: { type: Boolean, default: undefined },
|
||||
listHeight: Number,
|
||||
listItemHeight: Number,
|
||||
dropdownStyle: { type: Function as PropType<CSSProperties> },
|
||||
dropdownStyle: { type: Object as PropType<CSSProperties> },
|
||||
dropdownClassName: String,
|
||||
dropdownMatchSelectWidth: {
|
||||
type: [Boolean, Number] as PropType<boolean | number>,
|
||||
|
@ -275,7 +275,7 @@ export default function generateSelector<
|
|||
slots: ['option'],
|
||||
inheritAttrs: false,
|
||||
props: selectBaseProps<OptionType, DefaultValueType>(),
|
||||
setup(props) {
|
||||
setup(props, { expose }) {
|
||||
const useInternalProps = computed(
|
||||
() => props.internalProps && props.internalProps.mark === INTERNAL_PROPS_MARK,
|
||||
);
|
||||
|
@ -455,10 +455,10 @@ export default function generateSelector<
|
|||
labelInValue: mergedLabelInValue.value,
|
||||
optionLabelProp: mergedOptionLabelProp.value,
|
||||
});
|
||||
|
||||
return {
|
||||
...displayValue,
|
||||
disabled: isValueDisabled(val, valueOptions),
|
||||
option: valueOptions[0],
|
||||
};
|
||||
});
|
||||
|
||||
|
@ -947,10 +947,12 @@ export default function generateSelector<
|
|||
const blur = () => {
|
||||
selectorRef.value.blur();
|
||||
};
|
||||
return {
|
||||
expose({
|
||||
focus,
|
||||
blur,
|
||||
scrollTo: listRef.value?.scrollTo,
|
||||
scrollTo: (...args: any[]) => listRef.value?.scrollTo(...args),
|
||||
});
|
||||
return {
|
||||
tokenWithEnter,
|
||||
mockFocused,
|
||||
mergedId,
|
||||
|
@ -1139,7 +1141,7 @@ export default function generateSelector<
|
|||
menuItemSelectedIcon={menuItemSelectedIcon}
|
||||
virtual={virtual !== false && dropdownMatchSelectWidth !== false}
|
||||
onMouseenter={onPopupMouseEnter}
|
||||
v-slots={{ option: slots.option }}
|
||||
v-slots={{ ...slots, option: slots.option }}
|
||||
/>
|
||||
);
|
||||
|
||||
|
@ -1212,7 +1214,6 @@ export default function generateSelector<
|
|||
[`${prefixCls}-customize-input`]: customizeInputElement,
|
||||
[`${prefixCls}-show-search`]: mergedShowSearch,
|
||||
});
|
||||
|
||||
return (
|
||||
<div
|
||||
{...this.$attrs}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import type { ExportedSelectProps } from './Select';
|
||||
import Select from './Select';
|
||||
import Select, { selectProps } from './Select';
|
||||
import Option from './Option';
|
||||
import OptGroup from './OptGroup';
|
||||
import { selectBaseProps } from './generate';
|
||||
import type { ExtractPropTypes } from 'vue';
|
||||
|
||||
export type SelectProps<T = any> = Partial<ExtractPropTypes<ExportedSelectProps<T>>>;
|
||||
export { Option, OptGroup, selectBaseProps };
|
||||
export { Option, OptGroup, selectBaseProps, selectProps };
|
||||
|
||||
export default Select;
|
||||
|
|
|
@ -50,7 +50,7 @@ export const SelectContext = defineComponent({
|
|||
},
|
||||
});
|
||||
|
||||
export const useInjectSelectContext = () => {
|
||||
export const useInjectTreeSelectContext = () => {
|
||||
return inject(
|
||||
SelectContextKey,
|
||||
computed(() => ({} as ContextProps)),
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import type { DataNode, TreeDataNode, Key } from './interface';
|
||||
import { useInjectSelectContext } from './Context';
|
||||
import { useInjectTreeSelectContext } from './Context';
|
||||
import type { RefOptionListProps } from '../vc-select/OptionList';
|
||||
import type { ScrollTo } from '../vc-virtual-list/List';
|
||||
import { computed, defineComponent, nextTick, ref, watch } from 'vue';
|
||||
|
@ -36,7 +36,7 @@ export default defineComponent({
|
|||
slots: ['notFoundContent', 'menuItemSelectedIcon'],
|
||||
expose: ['scrollTo', 'onKeydown', 'onKeyup'],
|
||||
setup(props, { slots, expose }) {
|
||||
const context = useInjectSelectContext();
|
||||
const context = useInjectTreeSelectContext();
|
||||
|
||||
const treeRef = ref();
|
||||
const memoOptions = useMemo(
|
||||
|
@ -144,7 +144,7 @@ export default defineComponent({
|
|||
activeKey.value = key;
|
||||
};
|
||||
expose({
|
||||
scrollTo: treeRef.value?.scrollTo as ScrollTo,
|
||||
scrollTo: (...args: any[]) => treeRef.value.scrollTo?.(...args),
|
||||
onKeydown: (event: KeyboardEvent) => {
|
||||
const { which } = event;
|
||||
switch (which) {
|
||||
|
@ -217,7 +217,6 @@ export default defineComponent({
|
|||
if (mergedExpandedKeys.value) {
|
||||
treeProps.expandedKeys = mergedExpandedKeys.value;
|
||||
}
|
||||
|
||||
return (
|
||||
<div onMousedown={onListMouseDown} onMouseenter={onMouseenter}>
|
||||
{activeEntity.value && open && (
|
||||
|
@ -255,7 +254,7 @@ export default defineComponent({
|
|||
onExpand={onInternalExpand}
|
||||
onLoad={onTreeLoad}
|
||||
filterTreeNode={filterTreeNode}
|
||||
v-slots={{ checkable: context.value.customCheckable }}
|
||||
v-slots={{ ...slots, checkable: context.value.customCheckable }}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -91,7 +91,15 @@ export default function generate(config: {
|
|||
return defineComponent({
|
||||
name: 'TreeSelect',
|
||||
props: treeSelectProps(),
|
||||
slots: ['placeholder', 'maxTagPlaceholder', 'treeIcon', 'switcherIcon', 'notFoundContent'],
|
||||
slots: [
|
||||
'title',
|
||||
'placeholder',
|
||||
'maxTagPlaceholder',
|
||||
'treeIcon',
|
||||
'switcherIcon',
|
||||
'notFoundContent',
|
||||
'treeCheckable',
|
||||
],
|
||||
TreeNode,
|
||||
SHOW_ALL,
|
||||
SHOW_PARENT,
|
||||
|
@ -105,7 +113,6 @@ export default function generate(config: {
|
|||
// ======================= Tree Data =======================
|
||||
// FieldNames
|
||||
const mergedFieldNames = computed(() => fillFieldNames(props.fieldNames, true));
|
||||
|
||||
// Legacy both support `label` or `title` if not set.
|
||||
// We have to fallback to function to handle this
|
||||
const getTreeNodeTitle = (node: DataNode) => {
|
||||
|
@ -157,9 +164,9 @@ export default function generate(config: {
|
|||
const selectRef = ref(null);
|
||||
|
||||
expose({
|
||||
scrollTo: selectRef.value.scrollTo,
|
||||
focus: selectRef.value.focus,
|
||||
blur: selectRef.value.blur,
|
||||
scrollTo: (...args: any[]) => selectRef.value.scrollTo?.(...args),
|
||||
focus: () => selectRef.value.focus?.(),
|
||||
blur: () => selectRef.value?.blur(),
|
||||
|
||||
/** @private Internal usage. It's save to remove if `rc-cascader` not use it any longer */
|
||||
getEntityByValue,
|
||||
|
@ -477,7 +484,7 @@ export default function generate(config: {
|
|||
treeNodeFilterProp,
|
||||
getEntityByKey,
|
||||
getEntityByValue,
|
||||
customCheckable: slots.checkable,
|
||||
customCheckable: slots.treeCheckable,
|
||||
slots,
|
||||
};
|
||||
return (
|
||||
|
@ -496,6 +503,7 @@ export default function generate(config: {
|
|||
onSelect={null}
|
||||
onDeselect={null}
|
||||
onDropdownVisibleChange={onInternalDropdownVisibleChange}
|
||||
v-slots={slots}
|
||||
/>
|
||||
</SelectContext>
|
||||
);
|
||||
|
|
|
@ -78,6 +78,10 @@ function formatTreeData(
|
|||
node,
|
||||
};
|
||||
|
||||
if (node.slots) {
|
||||
dataNode.slots = node.slots;
|
||||
}
|
||||
|
||||
// Check `key` & `value` and warning user
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
if (
|
||||
|
|
|
@ -38,6 +38,8 @@ export interface InternalDataEntity {
|
|||
|
||||
/** Origin DataNode */
|
||||
node: DataNode;
|
||||
|
||||
slots?: Record<string, string>; // 兼容 V2
|
||||
}
|
||||
|
||||
export interface LegacyDataNode extends DataNode {
|
||||
|
|
|
@ -84,10 +84,6 @@ export default defineComponent({
|
|||
// abstract-drag-over-node is the top node
|
||||
dragOverNodeKey: null,
|
||||
});
|
||||
warning(
|
||||
!(props.treeData === undefined && props.children),
|
||||
'`children` of Tree is deprecated. Please use `treeData` instead.',
|
||||
);
|
||||
const treeData = computed(() => {
|
||||
return props.treeData !== undefined ? props.treeData : convertTreeToData(props.children);
|
||||
});
|
||||
|
@ -953,6 +949,7 @@ export default defineComponent({
|
|||
};
|
||||
expose({
|
||||
onNodeExpand,
|
||||
scrollTo,
|
||||
});
|
||||
onUnmounted(() => {
|
||||
window.removeEventListener('dragend', onWindowDragEnd);
|
||||
|
|
|
@ -22,7 +22,9 @@ export default defineComponent({
|
|||
setup(props, { attrs, slots, expose }) {
|
||||
warning(
|
||||
!('slots' in props.data),
|
||||
'treeData slots is deprecated, please use `v-slot:icon` or `v-slot:title`, `v-slot:switcherIcon` instead',
|
||||
`treeData slots is deprecated, please use ${Object.keys(props.data.slots || {}).map(
|
||||
key => '`v-slot:' + key + '` ',
|
||||
)}instead`,
|
||||
);
|
||||
const dragNodeHighlight = ref(false);
|
||||
const context = useInjectTreeContext();
|
||||
|
@ -346,7 +348,9 @@ export default defineComponent({
|
|||
// Icon + Title
|
||||
const renderSelector = () => {
|
||||
const {
|
||||
title = slots.title || context.value.slots?.[props.data?.slots?.title],
|
||||
title = slots.title ||
|
||||
context.value.slots?.[props.data?.slots?.title] ||
|
||||
context.value.slots?.title,
|
||||
selected,
|
||||
icon = slots.icon,
|
||||
loading,
|
||||
|
|
|
@ -1,49 +1,63 @@
|
|||
<template>
|
||||
<a-directory-tree
|
||||
v-model:expandedKeys="expandedKeys"
|
||||
v-model:selectedKeys="selectedKeys"
|
||||
multiple
|
||||
:tree-data1="treeData"
|
||||
<a-tree-select
|
||||
v-model:value="value"
|
||||
style="width: 100%"
|
||||
:dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
|
||||
:tree-data="treeData"
|
||||
placeholder="Please select"
|
||||
tree-default-expand-all
|
||||
>
|
||||
<a-tree-node key="0-0" title="ddd" class="test" style="color: red">
|
||||
<template #title="{ title }">{{ title }}</template>
|
||||
<a-tree-node key="0-0-0" title="leaf 0-0" is-leaf />
|
||||
<a-tree-node key="0-0-1" title="leaf 0-1" is-leaf />
|
||||
</a-tree-node>
|
||||
<a-tree-node key="0-1" title="parent 1">
|
||||
<a-tree-node key="0-1-0" title="leaf 1-0" is-leaf />
|
||||
<a-tree-node key="0-1-1" title="leaf 1-1" is-leaf />
|
||||
</a-tree-node>
|
||||
</a-directory-tree>
|
||||
<template #title1="{ key, value }">
|
||||
<span v-if="key === '0-0-1'" style="color: #08c">Child Node1 {{ value }}</span>
|
||||
</template>
|
||||
</a-tree-select>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref, watch } from 'vue';
|
||||
|
||||
interface TreeDataItem {
|
||||
value: string;
|
||||
key: string;
|
||||
title?: string;
|
||||
slots?: Record<string, string>;
|
||||
children?: TreeDataItem[];
|
||||
}
|
||||
|
||||
const treeData: TreeDataItem[] = [
|
||||
{
|
||||
title: 'Node1',
|
||||
value: '0-0',
|
||||
key: '0-0',
|
||||
children: [
|
||||
{
|
||||
value: '0-0-1',
|
||||
key: '0-0-1',
|
||||
slots: {
|
||||
title: 'title1',
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Child Node2',
|
||||
value: '0-0-2',
|
||||
key: '0-0-2',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Node2',
|
||||
value: '0-1',
|
||||
key: '0-1',
|
||||
},
|
||||
];
|
||||
export default defineComponent({
|
||||
setup() {
|
||||
const expandedKeys = ref<string[]>([]);
|
||||
const selectedKeys = ref<string[]>([]);
|
||||
const treeData = [
|
||||
{
|
||||
title: 'parent 0',
|
||||
key: '0-0',
|
||||
children: [
|
||||
{ title: 'leaf 0-0', key: '0-0-0', isLeaf: true },
|
||||
// { title: 'leaf 0-1', key: '0-0-1', isLeaf: true },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'parent 1',
|
||||
key: '0-1',
|
||||
children: [
|
||||
{ title: 'leaf 1-0', key: '0-1-0', isLeaf: true },
|
||||
{ title: 'leaf 1-1', key: '0-1-1', isLeaf: true },
|
||||
],
|
||||
},
|
||||
];
|
||||
const value = ref<string>();
|
||||
|
||||
watch(value, () => {
|
||||
console.log(value.value);
|
||||
});
|
||||
return {
|
||||
expandedKeys,
|
||||
selectedKeys,
|
||||
onTest: () => {},
|
||||
value,
|
||||
treeData,
|
||||
};
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue