index.mjs 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. import { shallowRef, triggerRef, onMounted, defineComponent, h, isVNode } from 'vue';
  2. import { flattedChildren } from '../../utils/vue/vnode.mjs';
  3. const getOrderedChildren = (vm, childComponentName, children) => {
  4. const nodes = flattedChildren(vm.subTree).filter((n) => {
  5. var _a;
  6. return isVNode(n) && ((_a = n.type) == null ? void 0 : _a.name) === childComponentName && !!n.component;
  7. });
  8. const uids = nodes.map((n) => n.component.uid);
  9. return uids.map((uid) => children[uid]).filter((p) => !!p);
  10. };
  11. const useOrderedChildren = (vm, childComponentName) => {
  12. const children = shallowRef({});
  13. const orderedChildren = shallowRef([]);
  14. const nodesMap = /* @__PURE__ */ new WeakMap();
  15. const addChild = (child) => {
  16. children.value[child.uid] = child;
  17. triggerRef(children);
  18. onMounted(() => {
  19. const childNode = child.getVnode().el;
  20. const parentNode = childNode.parentNode;
  21. if (!nodesMap.has(parentNode)) {
  22. nodesMap.set(parentNode, []);
  23. const originalFn = parentNode.insertBefore.bind(parentNode);
  24. parentNode.insertBefore = (node, anchor) => {
  25. const shouldSortChildren = nodesMap.get(parentNode).some((el) => node === el || anchor === el);
  26. if (shouldSortChildren)
  27. triggerRef(children);
  28. return originalFn(node, anchor);
  29. };
  30. }
  31. nodesMap.get(parentNode).push(childNode);
  32. });
  33. };
  34. const removeChild = (child) => {
  35. delete children.value[child.uid];
  36. triggerRef(children);
  37. const childNode = child.getVnode().el;
  38. const parentNode = childNode.parentNode;
  39. const childNodes = nodesMap.get(parentNode);
  40. const index = childNodes.indexOf(childNode);
  41. childNodes.splice(index, 1);
  42. };
  43. const sortChildren = () => {
  44. orderedChildren.value = getOrderedChildren(vm, childComponentName, children.value);
  45. };
  46. const IsolatedRenderer = (props) => {
  47. return props.render();
  48. };
  49. const ChildrenSorter = defineComponent({
  50. setup(_, { slots }) {
  51. return () => {
  52. sortChildren();
  53. return slots.default ? h(IsolatedRenderer, {
  54. render: slots.default
  55. }) : null;
  56. };
  57. }
  58. });
  59. return {
  60. children: orderedChildren,
  61. addChild,
  62. removeChild,
  63. ChildrenSorter
  64. };
  65. };
  66. export { useOrderedChildren };
  67. //# sourceMappingURL=index.mjs.map