vue-hooks-plus
Version:
Vue hooks library
107 lines (106 loc) • 3.78 kB
JavaScript
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
};