UNPKG

vue3-lazy-hydration

Version:
46 lines (45 loc) 1.59 kB
import { getCurrentInstance, onBeforeMount, onUnmounted, nextTick } from "vue"; import createHydrationCleanup from "../utils/create-hydration-cleanup.mjs"; import createHydrationPromise from "../utils/create-hydration-promise.mjs"; import trackDepsOnRender from "../utils/track-deps-on-render.mjs"; import waitForAsyncComponents from "../utils/wait-for-async-components.mjs"; import ensureParentHasSubTreeEl from "../utils/ensure-parent-has-subtree-el.mjs"; function useLazyHydration() { const instance = getCurrentInstance(); if (!instance || instance.isMounted) { throw new Error("useLazyHydration must be called from the setup method."); } const willPerformHydration = instance.vnode.el !== null; instance.vnode.type.__isLazilyHydrated = true; if (!willPerformHydration) { return { willPerformHydration, onHydrated: () => { } }; } const { cleanup, onCleanup } = createHydrationCleanup(); const { promise, resolvePromise: hydrate, onResolvedPromise: onBeforeHydrate } = createHydrationPromise(cleanup); const onHydrated = (cb) => onBeforeHydrate(() => nextTick(() => waitForAsyncComponents(instance, cb))); instance.type.__asyncLoader = () => promise; ensureParentHasSubTreeEl( instance.parent ); onBeforeMount(() => { instance.asyncDep = new Promise((r) => { r(true); }); }); onBeforeHydrate(() => { trackDepsOnRender( instance ); instance.asyncDep = null; }); onUnmounted(cleanup); return { willPerformHydration, hydrate, onHydrated, onCleanup }; } export { useLazyHydration as default };