ant-design-vue/components/vc-select/hooks/useCache.ts

56 lines
1.6 KiB
TypeScript

import type { Ref } from 'vue';
import { shallowRef, computed } from 'vue';
import type { RawValueType } from '../BaseSelect';
import type { DefaultOptionType, LabelInValueType } from '../Select';
/**
* Cache `value` related LabeledValue & options.
*/
export default (
labeledValues: Ref<LabelInValueType[]>,
valueOptions: Ref<Map<RawValueType, DefaultOptionType>>,
): [Ref<LabelInValueType[]>, (val: RawValueType) => DefaultOptionType] => {
const cacheRef = shallowRef({
values: new Map<RawValueType, LabelInValueType>(),
options: new Map<RawValueType, DefaultOptionType>(),
});
const filledLabeledValues = computed(() => {
const { values: prevValueCache, options: prevOptionCache } = cacheRef.value;
// Fill label by cache
const patchedValues = labeledValues.value.map(item => {
if (item.label === undefined) {
return {
...item,
label: prevValueCache.get(item.value)?.label,
};
}
return item;
});
// Refresh cache
const valueCache = new Map<RawValueType, LabelInValueType>();
const optionCache = new Map<RawValueType, DefaultOptionType>();
patchedValues.forEach(item => {
valueCache.set(item.value, item);
optionCache.set(
item.value,
valueOptions.value.get(item.value) || prevOptionCache.get(item.value),
);
});
cacheRef.value.values = valueCache;
cacheRef.value.options = optionCache;
return patchedValues;
});
const getOption = (val: RawValueType) =>
valueOptions.value.get(val) || cacheRef.value.options.get(val);
return [filledLabeledValues, getOption];
};