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

52 lines
1.6 KiB
TypeScript

import type { Ref } from 'vue';
import { shallowRef, watchEffect } from 'vue';
import type { FieldNames, RawValueType } from '../Select';
import { convertChildrenToData } from '../utils/legacyUtil';
/**
* Parse `children` to `options` if `options` is not provided.
* Then flatten the `options`.
*/
export default function useOptions<OptionType>(
options: Ref<OptionType[]>,
children: Ref<any>,
fieldNames: Ref<FieldNames>,
) {
const mergedOptions = shallowRef();
const valueOptions = shallowRef();
const labelOptions = shallowRef();
watchEffect(() => {
let newOptions = options.value;
const childrenAsData = !options.value;
if (childrenAsData) {
newOptions = convertChildrenToData(children.value);
}
const newValueOptions = new Map<RawValueType, OptionType>();
const newLabelOptions = new Map<any, OptionType>();
function dig(optionList: OptionType[], isChildren = false) {
// for loop to speed up collection speed
for (let i = 0; i < optionList.length; i += 1) {
const option = optionList[i];
if (!option[fieldNames.value.options] || isChildren) {
newValueOptions.set(option[fieldNames.value.value], option);
newLabelOptions.set(option[fieldNames.value.label], option);
} else {
dig(option[fieldNames.value.options], true);
}
}
}
dig(newOptions);
mergedOptions.value = newOptions;
valueOptions.value = newValueOptions;
labelOptions.value = newLabelOptions;
});
return {
options: mergedOptions,
valueOptions,
labelOptions,
};
}