UNPKG

vue-hooks-plus

Version:
107 lines (106 loc) 3.78 kB
import { ref, computed, unref, watchEffect, readonly } from "vue"; const EXTERNAL_USED_COUNT = {}; const loadScript = (path, props = {}) => { const script = document.querySelector(`script[src="${path}"]`); if (!script) { const newScript = document.createElement("script"); newScript.src = path; Object.keys(props).forEach((key) => { newScript[key] = props[key]; }); newScript.setAttribute("data-status", "loading"); document.body.appendChild(newScript); return { ref: newScript, status: "loading" }; } return { ref: script, status: script.getAttribute("data-status") || "ready" }; }; const loadCss = (path, props = {}) => { const css = document.querySelector(`link[href="${path}"]`); if (!css) { const newCss = document.createElement("link"); newCss.rel = "stylesheet"; newCss.href = path; Object.keys(props).forEach((key) => { newCss[key] = props[key]; }); const isLegacyIECss = "hideFocus" in newCss; if (isLegacyIECss && newCss.relList) { newCss.rel = "preload"; newCss.as = "style"; } newCss.setAttribute("data-status", "loading"); document.head.appendChild(newCss); return { ref: newCss, status: "loading" }; } return { ref: css, status: css.getAttribute("data-status") || "ready" }; }; function useExternal(path, options) { const status = ref(path ? "loading" : "unset"); const hookRef = ref(); const path_ = computed(() => unref(path)); watchEffect((onInvalidate) => { var _a, _b, _c, _d; if (!path_.value) { status.value = "unset"; return; } const pathname = (_b = (_a = path_.value) == null ? void 0 : _a.replace(/[|#].*$/, "")) != null ? _b : ""; if ((options == null ? void 0 : options.type) === "css" || !(options == null ? void 0 : options.type) && /(^css!|\.css$)/.test(pathname)) { const result = loadCss((_c = path_.value) != null ? _c : "", options == null ? void 0 : options.css); hookRef.value = result.ref; status.value = result.status; } else if ((options == null ? void 0 : options.type) === "js" || !(options == null ? void 0 : options.type) && /(^js!|\.js$)/.test(pathname)) { const result = loadScript((_d = path_.value) != null ? _d : "", options == null ? void 0 : options.js); hookRef.value = result.ref; status.value = result.status; } else { console.error( "Cannot infer the type of external resource, and please provide a type ('js' | 'css'). Refer to the https://ahooks.js.org/hooks/dom/use-external/#options" ); } if (!hookRef.value) { return; } if (path_.value && EXTERNAL_USED_COUNT[path_.value] === void 0) { EXTERNAL_USED_COUNT[path_.value] = 1; } else { if (path_.value) EXTERNAL_USED_COUNT[path_.value] += 1; } const handler = (event) => { var _a2; const targetStatus = event.type === "load" ? "ready" : "error"; (_a2 = hookRef.value) == null ? void 0 : _a2.setAttribute("data-status", targetStatus); status.value = targetStatus; }; hookRef.value.addEventListener("load", handler); hookRef.value.addEventListener("error", handler); onInvalidate(() => { var _a2, _b2, _c2; (_a2 = hookRef.value) == null ? void 0 : _a2.removeEventListener("load", handler); (_b2 = hookRef.value) == null ? void 0 : _b2.removeEventListener("error", handler); if (path_.value) EXTERNAL_USED_COUNT[path_.value] -= 1; if (path_.value && EXTERNAL_USED_COUNT[path_.value] === 0) { (_c2 = hookRef.value) == null ? void 0 : _c2.remove(); } hookRef.value = void 0; }); }); return readonly(status); } export { useExternal as default };