vue3-lazy-hydration
Version:
Lazy Hydration for Vue 3 SSR
66 lines (65 loc) • 1.71 kB
JavaScript
import { getCurrentInstance, unref, onMounted } from "vue";
import getRootElements from "../utils/get-root-elements.mjs";
function useHydrateOnInteraction({
willPerformHydration,
hydrate,
onCleanup
}, events = ["focus"]) {
if (!willPerformHydration) {
return;
}
const instance = getCurrentInstance();
if (!instance || instance.isMounted) {
throw new Error(
"useHydrateOnInteraction must be called from the setup method."
);
}
const eventsTypes = unref(events);
onMounted(() => {
const targets = getRootElements(instance);
const container = targets.length > 1 ? targets[0].parentElement || document : targets[0];
const eventListenerOptions = {
capture: true,
once: false,
passive: true
};
const listener = (event) => {
event.stopPropagation();
const paths = event.composedPath && event.composedPath() || event.path;
if (!paths) {
let el = event.target;
while (el) {
if (targets.includes(el)) {
hydrate();
return;
}
if (el === container) {
return;
}
el = el.parentElement;
}
return;
}
targets.forEach((target) => {
if (paths.includes(target)) {
hydrate();
}
});
};
eventsTypes.forEach((eventType) => {
container.addEventListener(eventType, listener, eventListenerOptions);
});
onCleanup(() => {
eventsTypes.forEach((eventType) => {
container.removeEventListener(
eventType,
listener,
eventListenerOptions
);
});
});
});
}
export {
useHydrateOnInteraction as default
};