componentAsync.ts 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. import { isArray, isObject, isPromise } from '@vue/shared'
  2. import { defineAsyncComponent } from '../apiAsyncComponent'
  3. import type { Component } from '../component'
  4. import { isVNode } from '../vnode'
  5. interface LegacyAsyncOptions {
  6. component: Promise<Component>
  7. loading?: Component
  8. error?: Component
  9. delay?: number
  10. timeout?: number
  11. }
  12. type LegacyAsyncReturnValue = Promise<Component> | LegacyAsyncOptions
  13. type LegacyAsyncComponent = (
  14. resolve?: (res: LegacyAsyncReturnValue) => void,
  15. reject?: (reason?: any) => void,
  16. ) => LegacyAsyncReturnValue | undefined
  17. const normalizedAsyncComponentMap = new WeakMap<
  18. LegacyAsyncComponent,
  19. Component
  20. >()
  21. export function convertLegacyAsyncComponent(
  22. comp: LegacyAsyncComponent,
  23. ): Component {
  24. if (normalizedAsyncComponentMap.has(comp)) {
  25. return normalizedAsyncComponentMap.get(comp)!
  26. }
  27. // we have to call the function here due to how v2's API won't expose the
  28. // options until we call it
  29. let resolve: (res: LegacyAsyncReturnValue) => void
  30. let reject: (reason?: any) => void
  31. const fallbackPromise = new Promise<Component>((r, rj) => {
  32. ;((resolve = r), (reject = rj))
  33. })
  34. const res = comp(resolve!, reject!)
  35. let converted: Component
  36. if (isPromise(res)) {
  37. converted = defineAsyncComponent(() => res)
  38. } else if (isObject(res) && !isVNode(res) && !isArray(res)) {
  39. converted = defineAsyncComponent({
  40. loader: () => res.component,
  41. loadingComponent: res.loading,
  42. errorComponent: res.error,
  43. delay: res.delay,
  44. timeout: res.timeout,
  45. })
  46. } else if (res == null) {
  47. converted = defineAsyncComponent(() => fallbackPromise)
  48. } else {
  49. converted = comp as any // probably a v3 functional comp
  50. }
  51. normalizedAsyncComponentMap.set(comp, converted)
  52. return converted
  53. }