apiCreateIf.ts 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445
  1. import { IF_ANCHOR_LABEL } from '@vue/shared'
  2. import { type Block, type BlockFn, insert } from './block'
  3. import { advanceHydrationNode, isHydrating } from './dom/hydration'
  4. import {
  5. insertionAnchor,
  6. insertionParent,
  7. resetInsertionState,
  8. } from './insertionState'
  9. import { renderEffect } from './renderEffect'
  10. import { DynamicFragment } from './fragment'
  11. export function createIf(
  12. condition: () => any,
  13. b1: BlockFn,
  14. b2?: BlockFn,
  15. once?: boolean,
  16. ): Block {
  17. const _insertionParent = insertionParent
  18. const _insertionAnchor = insertionAnchor
  19. if (!isHydrating) resetInsertionState()
  20. let frag: Block
  21. if (once) {
  22. frag = condition() ? b1() : b2 ? b2() : []
  23. } else {
  24. frag =
  25. isHydrating || __DEV__
  26. ? new DynamicFragment(IF_ANCHOR_LABEL)
  27. : new DynamicFragment()
  28. renderEffect(() => (frag as DynamicFragment).update(condition() ? b1 : b2))
  29. }
  30. if (!isHydrating) {
  31. if (_insertionParent) insert(frag, _insertionParent, _insertionAnchor)
  32. } else {
  33. // if _insertionAnchor is defined, insertionParent contains a static node
  34. // that should be skipped during hydration.
  35. // Advance to the next sibling node to bypass this static node.
  36. if (_insertionAnchor !== undefined) {
  37. advanceHydrationNode(_insertionParent!)
  38. }
  39. }
  40. return frag
  41. }