refactor: tree-select
							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, | ||||
|     }; | ||||
|   }, | ||||
| }); | ||||
|  |  | |||
							
								
								
									
										2
									
								
								v2-doc
								
								
								
								
							
							
								
								
								
								
								
								
							
						
						
									
										2
									
								
								v2-doc
								
								
								
								
							|  | @ -1 +1 @@ | |||
| Subproject commit 2e39bc81a84e2cfa90e8863e8f18d5a3d3ab1995 | ||||
| Subproject commit 3f94a02d16bac2377d71e26948ffe45571dae49e | ||||
		Loading…
	
		Reference in New Issue
	
	 tangjinzhou
						tangjinzhou