当前位置: 首页 > news >正文

vue 3 计算器

效果:

<template><div class="calculator-container"><div class="calculator"><!-- 显示区域 --><div class="display">{{ formattedDisplay }}</div><!-- 按钮区域 --><div class="buttons"><button @click="clear">C</button><button @click="appendParentheses">()</button><button @click="backspace">⌫</button><button @click="append('/')">÷</button><button @click="append('7')">7</button><button @click="append('8')">8</button><button @click="append('9')">9</button><button @click="append('*')">×</button><button @click="append('4')">4</button><button @click="append('5')">5</button><button @click="append('6')">6</button><button @click="append('-')">−</button><button @click="append('1')">1</button><button @click="append('2')">2</button><button @click="append('3')">3</button><button @click="append('+')">+</button><button @click="append('%')">%</button><button @click="append('0')">0</button><button @click="append('.')">.</button><button class="equals" @click="calculate">=</button></div></div></div>
</template><script setup lang="ts" >
import { ref, computed } from "vue";
import { evaluate } from "mathjs";// 表达式和显示内容
const expression = ref("");
const display = ref("0");// 格式化显示内容:将 * → ×,/ → ÷
const formattedDisplay = computed(() => {return expression.value.replace(/\*/g, "×").replace(/\//g, "÷");
});// 添加字符到表达式
function append(char:string) {const expr = expression.value;const lastChar = expr.slice(-1);// 如果表达式为空,且输入非法起始字符(如 + - * / % )),则阻止if (expr === "" && ["+", "-", "*", "/", "%", ")"].includes(char)) {return;}// 特别允许:如果前一个是左括号,并且当前字符是 + - 数字 → 允许if (lastChar === "(" && (["+", "-"].includes(char) || /\d/.test(char))) {expression.value += char;updateDisplay();return;}// 特别阻止:如果前一个是左括号,并且当前字符是 * / × ÷ % ( . → 不允许if (lastChar === "(" && ["*", "/", "×", "÷", "%", "(", "."].includes(char)) {return;}// 阻止连续运算符(比如 ++, +*, -- 等)const operators = ["+", "-", "*", "/", "×", "÷", "%"];if (operators.includes(lastChar) && operators.includes(char)) {return;}// 阻止非法插入:数字或右括号后插入左括号 (if ((/[\d]/.test(lastChar) || lastChar === ")") && char === "(") {return;}// 默认情况下允许添加字符(包括继续输入数字、小数点、括号等)expression.value += char;updateDisplay();
}// 清除输入
function clear() {expression.value = "";updateDisplay();
}// 删除最后一个字符
function backspace() {expression.value = expression.value.slice(0, -1);updateDisplay();
}// 插入括号:智能判断插入 '(' 还是 ')'
function appendParentheses() {const expr = expression.value;const lastChar = expr.slice(-1);// 第一步:统计所有未闭合的左括号数量let openCount = 0;for (let i = 0; i < expr.length; i++) {if (expr[i] === '(') openCount++;else if (expr[i] === ')') openCount--;}// 第二步:如果最后一个字符是 ( → 强制插入 )if (lastChar === '(') {expression.value += ')';updateDisplay();return;}// 第三步:如果有未闭合的左括号,允许插入 )if (openCount > 0) {expression.value += ')';updateDisplay();return;}// 第四步:如果前一个是数字或 ) → 不允许插入新的 (if (expr && /[\d)]/.test(lastChar)) {return;}// 第五步:没有未闭合的左括号,可以插入新的 (expression.value += '(';updateDisplay();
}// 执行计算
function calculate() {try {let expr = expression.value.replace(/(\d+)%/g, "($1 / 100)");expr = expr.replace(/\^/g, "**");const result = evaluate(expr).toString();expression.value = result;updateDisplay();} catch (e) {display.value = "错误";}
}// 更新显示内容
function updateDisplay() {display.value = formattedDisplay.value || "0";
}
</script><style scoped>
.calculator-container {display: flex;justify-content: center;align-items: center;min-height: 100vh;background-color: #f4f4f4;
}.calculator {background-color: #fff;border-radius: 12px;box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);padding: 20px;width: 320px;max-width: 100%;
}.display {width: 100%;height: 60px;font-size: 2rem;text-align: right;padding: 10px 15px;margin-bottom: 15px;background-color: #eaeaea;border-radius: 8px;overflow-x: auto;white-space: nowrap;
}.buttons {display: grid;grid-template-columns: repeat(4, 1fr);gap: 10px;
}.buttons button {width: 100%;height: 60px;font-size: 1.2rem;border: none;border-radius: 8px;background-color: #f0f0f0;cursor: pointer;transition: background-color 0.2s ease;
}.buttons button:hover {background-color: #ddd;
}.buttons button:active {background-color: #ccc;
}/* 特殊按钮:等号 */
.buttons button.equals {background-color: #ff9800 !important;color: #000 !important;font-weight: bold;
}
</style>

 

相关文章:

  • 邦策网站建设长沙网站推广
  • 福州网站怎么做的贵州seo技术查询
  • 网站页面一般做多大网站多少钱
  • 荆州做网站公司线上运营的5个步骤
  • 王建设医生个人网站seo深圳培训班
  • 织梦网站维护html网页制作用什么软件
  • MySql:DDL,增删改查:创建表
  • 【大模型学习】项目练习:套壳DeepSeek
  • 火山 RTC 引擎14 设置CB
  • (LeetCode 面试经典 150 题 )121. 买卖股票的最佳时机 (遍历)
  • 自然语言处理入门
  • 【开源项目】比 PyInstaller 更方便:图形界面打包 Python 脚本的体验
  • 工程优化——WebSocket、WSS(WebSocket Secure)和SSE(Server-Sent Events)通信对比
  • PyEcharts教程(009):PyEcharts绘制水球图
  • 常见网络知识,宽带、路由器
  • 【教学类-89-08】20250624新年篇05——元宵节灯笼2CM黏贴边(倒置和正立数字 )
  • 内存泄漏和内存溢出的区别
  • 五种 IO 模式的简单介绍 -- 阻塞 IO,非阻塞 IO,信号驱动 IO,IO 多路复用,异步 IO
  • 使用 PyFluent 自动化 CFD
  • FPGA基础 -- Verilog 验证平台之 **cocotb 验证 `阶乘计算模块(factorial)` 的例子**
  • CRMEB PHP多门店版v3.2.1系统全开源+Uniapp前端+搭建教程
  • 用vscode破解最新typora1.10.8
  • 前端vue2每三十秒被动接受后端服务器发送过来得数据
  • 服务器数据恢复——异常断电导致服务器故障的数据恢复案例
  • 编程语言的发展逻辑:从人类认知到人工智能协同
  • C预处理详解2