createSlots.ts 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. import { isArray } from '@vue/shared'
  2. import type { VNode } from '../vnode'
  3. // #6651 res can be undefined in SSR in string push mode
  4. type SSRSlot = (...args: any[]) => VNode[] | undefined
  5. interface CompiledSlotDescriptor {
  6. name: string
  7. fn: SSRSlot
  8. key?: string
  9. }
  10. /**
  11. * Compiler runtime helper for creating dynamic slots object
  12. * @private
  13. */
  14. export function createSlots(
  15. slots: Record<string, SSRSlot>,
  16. dynamicSlots: (
  17. | CompiledSlotDescriptor
  18. | CompiledSlotDescriptor[]
  19. | undefined
  20. )[],
  21. ): Record<string, SSRSlot> {
  22. for (let i = 0; i < dynamicSlots.length; i++) {
  23. const slot = dynamicSlots[i]
  24. // array of dynamic slot generated by <template v-for="..." #[...]>
  25. if (isArray(slot)) {
  26. for (let j = 0; j < slot.length; j++) {
  27. slots[slot[j].name] = slot[j].fn
  28. }
  29. } else if (slot) {
  30. // conditional single slot generated by <template v-if="..." #foo>
  31. slots[slot.name] = slot.key
  32. ? (...args: any[]) => {
  33. const res = slot.fn(...args)
  34. // attach branch key so each conditional branch is considered a
  35. // different fragment
  36. if (res) (res as any).key = slot.key
  37. return res
  38. }
  39. : slot.fn
  40. }
  41. }
  42. return slots
  43. }