From ca9b59473a7618420835ba528d6f63032f3a6d27 Mon Sep 17 00:00:00 2001 From: morningbao <747651423@qq.com> Date: Mon, 2 Dec 2024 16:04:00 +0800 Subject: [PATCH] =?UTF-8?q?fix(Select):=20=E5=A2=9E=E5=8A=A0option=20cache?= =?UTF-8?q?=EF=BC=8C=E9=81=BF=E5=85=8D=E6=90=9C=E7=B4=A2=E8=BF=87=E6=BB=A4?= =?UTF-8?q?=E6=97=B6optionsList=E4=B8=BA=E7=A9=BA=E5=AF=BC=E8=87=B4?= =?UTF-8?q?=E9=80=89=E4=B8=AD=E9=80=89=E9=A1=B9=E6=98=BE=E7=A4=BA=E5=BC=82?= =?UTF-8?q?=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/select/hooks/useSelectOptions.ts | 4 +++- src/select/select.tsx | 30 ++++++++++++++++++++++++---- src/select/util.ts | 18 ++++++++--------- 3 files changed, 37 insertions(+), 15 deletions(-) diff --git a/src/select/hooks/useSelectOptions.ts b/src/select/hooks/useSelectOptions.ts index 1f1a103b3..673fdbc9a 100644 --- a/src/select/hooks/useSelectOptions.ts +++ b/src/select/hooks/useSelectOptions.ts @@ -28,6 +28,7 @@ export default function useSelectOptions( ) { // 内部 options 记录 const options = ref([]); + const optionsCache = ref([]); // 指向当前 slots 数组,用来判断 slot 是否被更新 let innerSlotRecord: VNode[] = null; @@ -113,7 +114,7 @@ export default function useSelectOptions( const optionsMap = computed(() => { const res = new Map(); - optionsList.value.forEach((option: TdOptionProps) => { + optionsCache.value.concat(optionsList.value).forEach((option: TdOptionProps) => { res.set(option.value, option); }); return res; @@ -154,5 +155,6 @@ export default function useSelectOptions( options, optionsMap, optionsList, + optionsCache, }; } diff --git a/src/select/select.tsx b/src/select/select.tsx index 8819ed3e4..ff0d35268 100644 --- a/src/select/select.tsx +++ b/src/select/select.tsx @@ -94,7 +94,9 @@ export default defineComponent({ value: props.keys?.value || 'value', disabled: props.keys?.disabled || 'disabled', })); - const { options: innerOptions, optionsMap, optionsList } = useSelectOptions(props, instance, keys); + const { + options: innerOptions, optionsMap, optionsList, optionsCache, + } = useSelectOptions(props, instance, keys); const [value, setValue] = useVModel(valueProps, props.defaultValue, props.onChange, 'change'); const innerValue = computed(() => { @@ -164,6 +166,23 @@ export default defineComponent({ [labelOfKeys]: get(option, labelOfKeys), }; }; + const addCache = (val: SelectValue) => { + if (multiple.value) { + const newCache: TdOptionProps[] = []; + (val as SelectValue[]).forEach((item) => { + const option = optionsMap.value.get(item); + if (option) { + newCache.push(option); + } + }); + optionsCache.value = Array.from(new Set([...newCache, ...optionsCache.value])); + } else { + const option = optionsMap.value.get(val); + if (option) { + optionsCache.value = Array.from(new Set([option, ...optionsCache.value])); + } + } + }; const getSelectedOption = (newVal: SelectValue) => { let selectedOption: SelectValue = getOriginOptions(newVal); if (!selectedOption && optionValue) { @@ -194,6 +213,9 @@ export default defineComponent({ // eslint-disable-next-line dot-notation outputContext['option'] = outputContextOption; } + nextTick(() => { + addCache(newVal); + }); setValue(newVal, outputContext); }; @@ -232,7 +254,7 @@ export default defineComponent({ () => ((!multiple.value && innerPopupVisible.value && ((valueType.value === 'object' && (value.value?.[keys.value.label] || innerValue.value)) - || getSingleContent(innerValue.value, optionsList.value))) + || getSingleContent(innerValue.value, optionsMap.value))) || placeholder.value) ?? t(global.value.placeholder), ); @@ -242,12 +264,12 @@ export default defineComponent({ if (valueType.value === 'object') { return (value.value as SelectValue[]).map((v) => v[keys.value.label]); } - return getMultipleContent(innerValue.value as SelectValue[], optionsList.value); + return getMultipleContent(innerValue.value as SelectValue[], optionsMap.value); } if (valueType.value === 'object') { return value.value?.[keys.value.label] || innerValue.value; } - return getSingleContent(innerValue.value, optionsList.value); + return getSingleContent(innerValue.value, optionsMap.value); }); const valueDisplayParams = computed(() => { diff --git a/src/select/util.ts b/src/select/util.ts index 229587337..b7d64bd97 100644 --- a/src/select/util.ts +++ b/src/select/util.ts @@ -4,20 +4,18 @@ import { SelectOption, SelectOptionGroup, SelectValue, TdOptionProps, TdSelectProps, } from './type'; -export const getSingleContent = (value: TdSelectProps['value'], options: SelectOption[]): string => { - for (const option of options) { - if ((option as TdOptionProps).value === value) { - // 保底使用 value 作为显示 - return option?.label || String((option as TdOptionProps).value); - } - } - return value !== undefined && value !== null ? String(value) : undefined; +export const getSingleContent = ( + value: TdSelectProps['value'], + optionsMap: Map, TdOptionProps>, +): string => { + const option = optionsMap.get(value); + return option?.label || value?.toString(); }; -export const getMultipleContent = (value: SelectValue[], options: SelectOption[]) => { +export const getMultipleContent = (value: SelectValue[], optionsMap: Map, TdOptionProps>) => { const res: string[] = []; for (const iterator of value) { - const resLabel = getSingleContent(iterator, options); + const resLabel = getSingleContent(iterator, optionsMap); if (resLabel) { res.push(resLabel); }