refactor: tree-select

pull/4577/head
tangjinzhou 3 years ago
parent 1581943eb0
commit 76ee4d6856

@ -17,7 +17,13 @@ const initDefaultProps = <T>(
Object.keys(defaultProps).forEach(k => {
const prop = propTypes[k] as VueTypeValidableDef;
if (prop) {
prop.default = defaultProps[k];
if (prop.type || prop.default) {
prop.default = defaultProps[k];
} else if (prop.def) {
prop.def(defaultProps[k]);
} else {
propTypes[k] = { type: prop, default: defaultProps[k] };
}
} else {
throw new Error(`not have ${k} prop`);
}

@ -11,8 +11,6 @@ import VcTreeSelect, {
import classNames from '../_util/classNames';
import initDefaultProps from '../_util/props-util/initDefaultProps';
import type { SizeType } from '../config-provider';
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';
import omit from '../_util/omit';
import PropTypes from '../_util/vue-types';
@ -237,78 +235,6 @@ const TreeSelect = defineComponent({
);
};
},
methods: {
saveTreeSelect(node: any) {
this.vcTreeSelect = node;
},
focus() {
this.vcTreeSelect.focus();
},
blur() {
this.vcTreeSelect.blur();
},
renderSwitcherIcon(prefixCls: string, { isLeaf, loading }) {
if (loading) {
return <LoadingOutlined class={`${prefixCls}-switcher-loading-icon`} />;
}
if (isLeaf) {
return null;
}
return <CaretDownOutlined class={`${prefixCls}-switcher-icon`} />;
},
handleChange(...args: any[]) {
this.$emit('update:value', args[0]);
this.$emit('change', ...args);
},
handleTreeExpand(...args: any[]) {
this.$emit('update:treeExpandedKeys', args[0]);
this.$emit('treeExpand', ...args);
},
handleSearch(...args: any[]) {
this.$emit('update:searchValue', args[0]);
this.$emit('search', ...args);
},
updateTreeData(treeData: any[]) {
const { $slots } = this;
const defaultFields = {
children: 'children',
title: 'title',
key: 'key',
label: 'label',
value: 'value',
};
const replaceFields = { ...defaultFields, ...this.$props.replaceFields };
return treeData.map(item => {
const { slots = {} } = item;
const label = item[replaceFields.label];
const title = item[replaceFields.title];
const value = item[replaceFields.value];
const key = item[replaceFields.key];
const children = item[replaceFields.children];
let newLabel = typeof label === 'function' ? label() : label;
let newTitle = typeof title === 'function' ? title() : title;
if (!newLabel && slots.label && $slots[slots.label]) {
newLabel = <>{$slots[slots.label](item)}</>;
}
if (!newTitle && slots.title && $slots[slots.title]) {
newTitle = <>{$slots[slots.title](item)}</>;
}
const treeNodeProps = {
...item,
title: newTitle || newLabel,
value,
dataRef: item,
key,
};
if (children) {
return { ...treeNodeProps, children: this.updateTreeData(children) };
}
return treeNodeProps;
});
},
},
});
/* istanbul ignore next */

@ -8,6 +8,7 @@ import PropTypes from '../_util/vue-types';
import { filterEmpty } from '../_util/props-util';
import initDefaultProps from '../_util/props-util/initDefaultProps';
import type { DataNode, DragNodeEvent, FieldNames, Key } from '../vc-tree/interface';
import type { TreeNodeProps } from '../vc-tree/props';
import { treeProps as vcTreeProps } from '../vc-tree/props';
import useConfigInject from '../_util/hooks/useConfigInject';
import renderSwitcherIcon from './utils/iconUtil';
@ -35,7 +36,7 @@ export interface AntdTreeNodeAttribute {
disableCheckbox: boolean;
}
export type AntTreeNodeProps = DataNode;
export type AntTreeNodeProps = TreeNodeProps;
// [Legacy] Compatible for v2
export type TreeDataItem = DataNode;

@ -11,7 +11,6 @@ export {
AntTreeNodeCheckedEvent,
AntTreeNodeSelectedEvent,
AntdTreeNodeAttribute,
AntTreeNodeProps,
TreeDataItem,
} from './Tree';

@ -1,4 +1,4 @@
import type { DataNode, Key } from 'ant-design-vue/es/vc-tree/interface';
import type { DataNode, Key } from '../../vc-tree/interface';
enum Record {
None,

@ -4,7 +4,7 @@ import MinusSquareOutlined from '@ant-design/icons-vue/MinusSquareOutlined';
import PlusSquareOutlined from '@ant-design/icons-vue/PlusSquareOutlined';
import CaretDownFilled from '@ant-design/icons-vue/CaretDownFilled';
import type { AntTreeNodeProps } from '../Tree';
import { isValidElement } from 'ant-design-vue/es/_util/props-util';
import { isValidElement } from '../../_util/props-util';
import { cloneVNode } from 'vue';

@ -5,7 +5,7 @@ import type { VNodeChild } from 'vue';
import { Fragment } 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';
import { useInjectTreeSelectContext } from '../../vc-tree-select/Context';
interface SelectorProps extends InnerSelectorProps {
inputElement: VNodeChild;

@ -1034,7 +1034,7 @@ export default function generateSelector<
internalProps = {},
...restProps
} = props; //as SelectProps<OptionType[], ValueType>;
} = { ...props, ...attrs }; //as SelectProps<OptionType[], ValueType>;
// ============================= Input ==============================
// Only works in `combobox`
const customizeInputElement: VNodeChild | JSX.Element =
@ -1144,9 +1144,8 @@ export default function generateSelector<
});
return (
<div
{...attrs}
class={mergedClassName}
{...domProps}
class={mergedClassName}
ref={containerRef}
onMousedown={onInternalMouseDown}
onKeydown={onInternalKeyDown}

@ -143,7 +143,7 @@ export default defineComponent({
activeKey.value = key;
};
expose({
scrollTo: (...args: any[]) => treeRef.value.scrollTo?.(...args),
scrollTo: (...args: any[]) => treeRef.value?.scrollTo?.(...args),
onKeydown: (event: KeyboardEvent) => {
const { which } = event;
switch (which) {

@ -64,6 +64,7 @@ const OMIT_PROPS: (keyof TreeSelectProps)[] = [
'treeDataSimpleMode',
'treeNodeLabelProp',
'treeDefaultExpandedKeys',
'bordered',
];
export default function generate(config: {
@ -236,8 +237,9 @@ export default function generate(config: {
...checkedKeys.map(key => getEntityByKey(key).data.value),
];
rawHalfCheckedKeys.value = halfCheckedKeys;
} else {
[rawValues.value, rawHalfCheckedKeys.value] = [newRawValues, valueHalfCheckedKeys];
}
[rawValues.value, rawHalfCheckedKeys.value] = [newRawValues, valueHalfCheckedKeys];
});
const selectValues = useSelectValues(rawValues, {
@ -378,7 +380,7 @@ export default function generate(config: {
option: DataNode,
source: SelectSource,
) => {
const eventValue = mergedLabelInValue.value ? selectValue : selectValue;
const eventValue = selectValue;
let newRawValues = removeValue(rawValues.value, selectValue);

@ -1,4 +1,4 @@
import { warning } from 'ant-design-vue/es/vc-util/warning';
import { warning } from '../../vc-util/warning';
import type { ComputedRef, Ref } from 'vue';
import { computed } from 'vue';
import type {
@ -76,6 +76,7 @@ function formatTreeData(
value: mergedValue,
title: getLabelProp(node),
node,
dataRef: node,
};
if (node.slots) {

@ -39,6 +39,8 @@ export interface InternalDataEntity {
/** Origin DataNode */
node: DataNode;
dataRef: DataNode;
slots?: Record<string, string>; // 兼容 V2
}

@ -11,9 +11,9 @@ import type {
} from '../interface';
import { fillLegacyProps } from './legacyUtil';
import type { SkipType } from '../hooks/useKeyValueMapping';
import type { FlattenNode } from 'ant-design-vue/es/vc-tree/interface';
import { flattenTreeData } from 'ant-design-vue/es/vc-tree/utils/treeUtil';
import type { FilterFunc } from 'ant-design-vue/es/vc-select/interface/generator';
import type { FlattenNode } from '../../vc-tree/interface';
import { flattenTreeData } from '../../vc-tree/utils/treeUtil';
import type { FilterFunc } from '../../vc-select/interface/generator';
type CompatibleDataNode = Omit<FlattenDataNode, 'level'>;

@ -1,12 +1,14 @@
import { warning } from '../../vc-util/warning';
import type { TreeSelectProps } from '../TreeSelect';
import { toArray } from './valueUtil';
function warningProps(props: TreeSelectProps) {
function warningProps(props: any) {
const { searchPlaceholder, treeCheckStrictly, treeCheckable, labelInValue, value, multiple } =
props;
warning(!searchPlaceholder, '`searchPlaceholder` has been removed.');
warning(
!searchPlaceholder,
'`searchPlaceholder` has been removed, please use `placeholder` instead',
);
if (treeCheckStrictly && labelInValue === false) {
warning(false, '`treeCheckStrictly` will force set `labelInValue` to `true`.');

@ -634,7 +634,7 @@ export default defineComponent({
checkedObj = newCheckedKeys;
// [Legacy] This is used for `rc-tree-select`
// [Legacy] This is used for vc-tree-select`
eventObj.checkedNodes = [];
eventObj.checkedNodesPositions = [];
eventObj.halfCheckedKeys = newHalfCheckedKeys;
@ -997,7 +997,6 @@ export default defineComponent({
const { class: className, style } = attrs;
const domProps = getDataAndAria({ ...props, ...attrs });
return (
<TreeContext
value={{

@ -402,8 +402,8 @@ export function convertNodePropsToEventData(props: TreeNodeProps): EventDataNode
pos,
active,
} = props;
const eventData = {
dataRef: data,
...data,
expanded,
selected,
@ -416,7 +416,6 @@ export function convertNodePropsToEventData(props: TreeNodeProps): EventDataNode
dragOverGapBottom,
pos,
active,
dataRef: data,
eventKey: data.key,
};
if (!('props' in eventData)) {

@ -1,40 +1,80 @@
<template>
<a-tree-select
v-model:value="value"
show-search
style="width: 100%"
:dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
placeholder="Please select"
allow-clear
multiple
tree-default-expand-all
>
<a-tree-select-node value="parent 1" title="parent 1">
<a-tree-select-node value="parent 1-0" title="parent 1-0">
<a-tree-select-node value="leaf1" title="my leaf" />
<a-tree-select-node value="leaf2" title="your leaf" />
</a-tree-select-node>
<a-tree-select-node value="parent 1-1" title="parent 1-1">
<a-tree-select-node value="sss">
<template #title><b style="color: #08c">sss</b></template>
</a-tree-select-node>
</a-tree-select-node>
</a-tree-select-node>
</a-tree-select>
<a-space direction="vertical" style="width: 100%">
<a-tree-select
v-model:value="value"
show-search
style="width: 100%"
:dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
placeholder="Please select"
allow-clear
tree-default-expand-all
:tree-data="treeData"
>
<template #suffixIcon><SmileOutlined /></template>
</a-tree-select>
<a-tree-select
v-model:value="value1"
show-search
style="width: 100%"
:dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
placeholder="Please select"
allow-clear
multiple
show-arrow
tree-default-expand-all
:tree-data="treeData"
>
<template #suffixIcon><SmileOutlined /></template>
</a-tree-select>
</a-space>
</template>
<script lang="ts">
import { SmileOutlined } from '@ant-design/icons-vue';
import { TreeSelectProps } from 'ant-design-vue';
import { defineComponent, ref, watch } from 'vue';
export default defineComponent({
components: {
SmileOutlined,
},
setup() {
const value = ref<string[]>([]);
const value1 = ref<string[]>([]);
const treeData = ref<TreeSelectProps['treeData']>([
{
title: 'parent 1',
value: 'parent 1',
children: [
{
title: 'parent 1-0',
value: 'parent 1-0',
children: [
{
title: 'my leaf',
value: 'leaf1',
},
{
title: 'your leaf',
value: 'leaf2',
},
],
},
{
title: 'parent 1-1',
value: 'parent 1-1',
},
],
},
]);
watch(value, () => {
console.log('select', value.value);
});
return {
value,
value1,
treeData,
};
},
});

@ -1 +1 @@
Subproject commit 2e39bc81a84e2cfa90e8863e8f18d5a3d3ab1995
Subproject commit 3f94a02d16bac2377d71e26948ffe45571dae49e
Loading…
Cancel
Save