UNPKG

@~gson/vue-calculator

Version:

A beautiful and functional Vue calculator component with theme customization and keyboard support

209 lines (208 loc) 6.4 kB
import { useCssVars as B, ref as r, onMounted as O, onUnmounted as S, createElementBlock as w, openBlock as E, createElementVNode as t, createCommentVNode as T, toDisplayString as m } from "vue"; const V = (o, k) => { const v = o.__vccOpts || o; for (const [a, n] of k) v[a] = n; return v; }, A = { class: "calculator" }, D = { class: "display-container" }, L = { class: "expression" }, j = { key: 0, class: "result" }, F = { class: "buttons" }, I = { __name: "App", props: { theme: { type: Object, default: () => ({ background: "#f5f7fa", display: "#ffffff", button: "#ffffff", operator: { background: "#a8e6cf", hover: "#88d7b5" }, equal: { background: "#ff9ff3", hover: "#f368e0" }, clear: { background: "#ff7675", hover: "#d63031" }, backspace: { background: "#e0e0e0", hover: "#d0d0d0" } }) }, confirmText: { type: String, default: "确认" } }, emits: ["confirm"], setup(o, { emit: k }) { B((l) => ({ "7a787720": o.theme.background, "2097c0c0": o.theme.display, "381b8774": o.theme.button, "221bd7b6": o.theme.operator.background, "7054d1b4": o.theme.operator.hover, "1ffa8c2c": o.theme.equal.background, e9e34200: o.theme.equal.hover, "7be33131": o.theme.clear.background, d617914e: o.theme.clear.hover, "6ad0debf": o.theme.backspace.background, "2a57c90b": o.theme.backspace.hover })); const v = k, a = r("0"), n = r(""), R = r(""), C = r(""), g = r(""), u = r(!1), i = r(""); O(() => { window.addEventListener("keydown", x); }), S(() => { window.removeEventListener("keydown", x); }); const s = (l) => { if (u.value && (a.value = "", u.value = !1), l === ".") { const e = n.value.split(/[+\-*/()\s]/).pop(); if (e && e.includes(".")) return; } a.value === "0" && l !== "." ? a.value = l : a.value += l, n.value += l, b(); }, c = (l) => { u.value && (u.value = !1), n.value += l, b(); }, p = (l) => { u.value && (a.value = "", u.value = !1), n.value += l, b(); }, y = (l) => { try { return new Function("return " + l)(); } catch { return NaN; } }, b = () => { if (n.value) try { let l = n.value.replace(/×/g, "*").replace(/÷/g, "/"); const e = y(l); isNaN(e) || (i.value = `= ${e}`); } catch { i.value = ""; } }, N = () => { if (n.value) try { let l = n.value.replace(/×/g, "*").replace(/÷/g, "/"); const e = y(l); if (isNaN(e)) { alert("无效的表达式"); return; } if (l.includes("/0")) { alert("除数不能为0"), f(); return; } const d = e.toString(); a.value = d, n.value = d, g.value = "", C.value = "", u.value = !0, i.value = d, v("confirm", d); } catch { alert("计算错误"), f(); } }, x = (l) => { const e = l.key; /[0-9.]/.test(e) ? s(e) : ["+", "-", "*", "/", "(", ")"].includes(e) ? e === "(" || e === ")" ? p(e) : c(e) : e === "Enter" ? N() : e === "Backspace" ? n.value.length > 0 && (n.value = n.value.slice(0, -1), a.value = a.value.slice(0, -1) || "0", b()) : e === "Escape" && f(); }, q = () => { n.value.length > 0 && (n.value = n.value.slice(0, -1), a.value = a.value.slice(0, -1) || "0", b()); }, f = () => { a.value = "0", n.value = "", R.value = "", C.value = "", g.value = "", i.value = "", u.value = !1; }; return (l, e) => (E(), w("div", A, [ t("div", D, [ t("div", L, m(n.value), 1), i.value ? (E(), w("div", j, m(i.value), 1)) : T("", !0) ]), t("div", F, [ t("button", { onClick: f, class: "btn clear" }, "C"), t("button", { onClick: e[0] || (e[0] = () => p("(")), class: "btn operator" }, "("), t("button", { onClick: e[1] || (e[1] = () => p(")")), class: "btn operator" }, ")"), t("button", { onClick: e[2] || (e[2] = () => c("*")), class: "btn operator" }, "×"), t("button", { onClick: e[3] || (e[3] = () => s("7")), class: "btn" }, "7"), t("button", { onClick: e[4] || (e[4] = () => s("8")), class: "btn" }, "8"), t("button", { onClick: e[5] || (e[5] = () => s("9")), class: "btn" }, "9"), t("button", { onClick: e[6] || (e[6] = () => c("/")), class: "btn operator" }, "/"), t("button", { onClick: e[7] || (e[7] = () => s("4")), class: "btn" }, "4"), t("button", { onClick: e[8] || (e[8] = () => s("5")), class: "btn" }, "5"), t("button", { onClick: e[9] || (e[9] = () => s("6")), class: "btn" }, "6"), t("button", { onClick: e[10] || (e[10] = () => c("+")), class: "btn operator" }, "+"), t("button", { onClick: e[11] || (e[11] = () => s("1")), class: "btn" }, "1"), t("button", { onClick: e[12] || (e[12] = () => s("2")), class: "btn" }, "2"), t("button", { onClick: e[13] || (e[13] = () => s("3")), class: "btn" }, "3"), t("button", { onClick: e[14] || (e[14] = () => c("-")), class: "btn operator" }, "-"), t("button", { onClick: e[15] || (e[15] = () => s(".")), class: "btn" }, "."), t("button", { onClick: e[16] || (e[16] = () => s("0")), class: "btn" }, "0"), t("button", { onClick: q, class: "btn operator-top" }, "⌫"), t("button", { onClick: N, class: "btn equal", style: { "grid-column": "span 1" } }, m(o.confirmText), 1) ]) ])); } }, M = /* @__PURE__ */ V(I, [["__scopeId", "data-v-8dc45829"]]); export { M as default };