59 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			TypeScript
		
	
	
			
		
		
	
	
			59 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			TypeScript
		
	
	
| import type { Ref } from 'vue';
 | |
| import { toRaw, shallowRef, watchEffect, watch } 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();
 | |
|   const tempMergedOptions = shallowRef([]);
 | |
|   watch(
 | |
|     [options, children],
 | |
|     () => {
 | |
|       if (options.value) {
 | |
|         tempMergedOptions.value = toRaw(options.value).slice();
 | |
|       } else {
 | |
|         tempMergedOptions.value = convertChildrenToData(children.value);
 | |
|       }
 | |
|     },
 | |
|     { immediate: true, deep: true },
 | |
|   );
 | |
|   watchEffect(() => {
 | |
|     const newOptions = tempMergedOptions.value;
 | |
| 
 | |
|     const newValueOptions = new Map<RawValueType, OptionType>();
 | |
|     const newLabelOptions = new Map<any, OptionType>();
 | |
|     const fieldNamesValue = fieldNames.value;
 | |
|     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[fieldNamesValue.options] || isChildren) {
 | |
|           newValueOptions.set(option[fieldNamesValue.value], option);
 | |
|           newLabelOptions.set(option[fieldNamesValue.label], option);
 | |
|         } else {
 | |
|           dig(option[fieldNamesValue.options], true);
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|     dig(newOptions);
 | |
|     mergedOptions.value = newOptions;
 | |
|     valueOptions.value = newValueOptions;
 | |
|     labelOptions.value = newLabelOptions;
 | |
|   });
 | |
|   return {
 | |
|     options: mergedOptions,
 | |
|     valueOptions,
 | |
|     labelOptions,
 | |
|   };
 | |
| }
 |