useOptions.js 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. import { toRaw, shallowRef, watchEffect, watch } from 'vue';
  2. import { convertChildrenToData } from '../utils/legacyUtil';
  3. /**
  4. * Parse `children` to `options` if `options` is not provided.
  5. * Then flatten the `options`.
  6. */
  7. export default function useOptions(options, children, fieldNames) {
  8. const mergedOptions = shallowRef();
  9. const valueOptions = shallowRef();
  10. const labelOptions = shallowRef();
  11. const tempMergedOptions = shallowRef([]);
  12. watch([options, children], () => {
  13. if (options.value) {
  14. tempMergedOptions.value = toRaw(options.value).slice();
  15. } else {
  16. tempMergedOptions.value = convertChildrenToData(children.value);
  17. }
  18. }, {
  19. immediate: true,
  20. deep: true
  21. });
  22. watchEffect(() => {
  23. const newOptions = tempMergedOptions.value;
  24. const newValueOptions = new Map();
  25. const newLabelOptions = new Map();
  26. const fieldNamesValue = fieldNames.value;
  27. function dig(optionList) {
  28. let isChildren = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
  29. // for loop to speed up collection speed
  30. for (let i = 0; i < optionList.length; i += 1) {
  31. const option = optionList[i];
  32. if (!option[fieldNamesValue.options] || isChildren) {
  33. newValueOptions.set(option[fieldNamesValue.value], option);
  34. newLabelOptions.set(option[fieldNamesValue.label], option);
  35. } else {
  36. dig(option[fieldNamesValue.options], true);
  37. }
  38. }
  39. }
  40. dig(newOptions);
  41. mergedOptions.value = newOptions;
  42. valueOptions.value = newValueOptions;
  43. labelOptions.value = newLabelOptions;
  44. });
  45. return {
  46. options: mergedOptions,
  47. valueOptions,
  48. labelOptions
  49. };
  50. }