index.ts 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. import type {
  2. ComponentInternalInstance,
  3. VNode,
  4. VNodeChild,
  5. VNodeNormalizedChildren,
  6. } from 'vue';
  7. import { isVNode } from 'vue';
  8. type VNodeChildAtom = Exclude<VNodeChild, Array<any>>;
  9. type RawSlots = Exclude<VNodeNormalizedChildren, Array<any> | null | string>;
  10. type FlattenVNodes = Array<RawSlots | VNodeChildAtom>;
  11. /**
  12. * @zh_CN Find the parent component upward
  13. * @param instance
  14. * @param parentNames
  15. */
  16. function findComponentUpward(
  17. instance: ComponentInternalInstance,
  18. parentNames: string[],
  19. ) {
  20. let parent = instance.parent;
  21. while (parent && !parentNames.includes(parent?.type?.name ?? '')) {
  22. parent = parent.parent;
  23. }
  24. return parent;
  25. }
  26. const flattedChildren = (
  27. children: FlattenVNodes | VNode | VNodeNormalizedChildren,
  28. ): FlattenVNodes => {
  29. const vNodes = Array.isArray(children) ? children : [children];
  30. const result: FlattenVNodes = [];
  31. vNodes.forEach((child) => {
  32. if (Array.isArray(child)) {
  33. result.push(...flattedChildren(child));
  34. } else if (isVNode(child) && Array.isArray(child.children)) {
  35. result.push(...flattedChildren(child.children));
  36. } else {
  37. result.push(child);
  38. if (isVNode(child) && child.component?.subTree) {
  39. result.push(...flattedChildren(child.component.subTree));
  40. }
  41. }
  42. });
  43. return result;
  44. };
  45. export { findComponentUpward, flattedChildren };