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( options: Ref, children: Ref, fieldNames: Ref, ) { 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(); const newLabelOptions = new Map(); 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, }; }