当前位置: 首页 > 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>

 

http://www.lryc.cn/news/574773.html

相关文章:

  • Nginx性能优化配置指南
  • 6.24_JAVA_微服务_Elasticsearch搜索
  • vscode + Jlink 一键调试stm32 单片机程序(windows系统版)
  • Git简介和常用命令
  • Windows安装Emscripten‌/emsdk(成功)
  • Python 数据分析与可视化 Day 6 - 可视化整合报告实战
  • Javaweb - 5 事件的绑定
  • 技术伦理之争:OpenAI陷抄袭风波,法院强制下架宣传视频
  • 自然语言处理入门
  • day041-web集群架构搭建
  • 软件设计模式选择、判断解析-1
  • 快速sincos算法,stm32测试
  • 用Rust写平衡三进制加法器
  • 【unitrix】 4.3 左移运算(<<)的实现(shl.rs)
  • 【WCF】单例模式的线程安全缓存管理器实现,给你的WebApi加入缓存吧
  • MyBatis Plus与P6Spy日志配置
  • leetcode230-二叉搜索树中第K小的元素
  • 【计算机网络】期末复习
  • 【教学类-89-08】20250624新年篇05——元宵节灯笼2CM黏贴边(倒置和正立数字 )
  • STM32学习笔记——中断控制
  • (C++)标准模板库(STL)相关介绍(C++教程)
  • C语言专题——关键字详解
  • 前端后端文件下载防抖实现方案
  • 浅谈开源在线客服系统与 APP 集成的技术方案与优劣势
  • 华为云Flexus+DeepSeek征文 | 基于华为云的 Dify-LLM 企业级 AI 开发平台部署指南
  • React Hooks详解
  • 开源跨平台的轻量 C# 编辑器
  • 想考华为HCIA-AI,应该怎么入门?
  • 第五课:大白话教你用K邻近算法做分类和回归
  • (三十六)深度解析领域特定语言(DSL)第七章——语法制导翻译——案例语义模型