vue自定义实现计算器组件(附完整代码)

 更新时间:2025年06月09日 11:23:10   作者:S筱潇S四维Smile  
这篇文章主要为大家详细介绍了如何使用Vue自定义实现一个计算器组件,文中的示例代码讲解详细,具有一定的借鉴价值,有需要的小伙伴可以参考一下

自定义组件实现以下简单的计算器功能:

创建计算器组件文件calculator.vue,代码如下:

<template>
  <div class="calculator">
 
    <!-- 当前运算过程显示区域 -->
    <div class="expression">{{ currentExpression }}</div>
 
    <!-- 计算器显示屏 -->
    <div class="display">{{ displayValue }}</div>
 
    <!-- 按钮区域 -->
    <div class="buttons">
      <el-button @click="clear">AC</el-button>
      <el-button @click="toggleSign">+/-</el-button>
      <el-button @click="inputPercent">%</el-button>
      <el-button @click="inputOperator('÷')" style="font-size: 22px;">÷</el-button>
 
      <el-button @click="inputDigit(7)">7</el-button>
      <el-button @click="inputDigit(8)">8</el-button>
      <el-button @click="inputDigit(9)">9</el-button>
      <el-button @click="inputOperator('*')">*</el-button>
 
      <el-button @click="inputDigit(4)">4</el-button>
      <el-button @click="inputDigit(5)">5</el-button>
      <el-button @click="inputDigit(6)">6</el-button>
      <el-button @click="inputOperator('-')">-</el-button>
 
      <el-button @click="inputDigit(1)">1</el-button>
      <el-button @click="inputDigit(2)">2</el-button>
      <el-button @click="inputDigit(3)">3</el-button>
      <el-button @click="inputOperator('+')">+</el-button>
 
      <el-button @click="inputDigit(0)" class="zero">0</el-button>
      <el-button @click="inputDot">.</el-button>
      <el-button @click="calculate">=</el-button>
    </div>
  </div>
</template>
 
<script>
  export default {
    data() {
      return {
        displayValue: '0', // 显示的值
        firstOperand: null, // 第一个操作数
        waitingForSecondOperand: false, // 是否等待第二个操作数
        operator: null, // 当前的操作符
        currentExpression: '' // 用于存储当前运算过程
      };
    },
    methods: {
      // 输入数字
      inputDigit(digit) {
        // 如果运算结束并开始输入新数字,清空计算过程和显示屏
        if (this.firstOperand !== null && this.operator === null) {
          this.displayValue = String(digit);
          this.currentExpression = ''; // 清空当前运算过程
          this.firstOperand = null; // 重置操作数
        } else if (this.waitingForSecondOperand) {
          this.displayValue = String(digit);
          this.waitingForSecondOperand = false;
        } else {
          this.displayValue = this.displayValue === '0' ? String(digit) : this.displayValue + String(digit);
        }
        this.updateExpression();
      },
      // 输入小数点
      inputDot() {
        if (!this.displayValue.includes('.')) {
          this.displayValue += '.';
        }
        this.updateExpression();
      },
      // 处理运算符
      inputOperator(nextOperator) {
        const inputValue = parseFloat(this.displayValue);
 
        if (this.operator && this.waitingForSecondOperand) {
          this.operator = nextOperator;
          this.updateExpression();
          return;
        }
 
        if (this.firstOperand === null) {
          this.firstOperand = inputValue;
        } else if (this.operator) {
          const result = this.performCalculation(this.firstOperand, inputValue, this.operator);
          this.displayValue = String(result);
          this.firstOperand = result;
        }
 
        this.waitingForSecondOperand = true;
        this.operator = nextOperator;
        this.updateExpression();
      },
      // 执行计算
      performCalculation(firstOperand, secondOperand, operator) {
        switch (operator) {
          case '+':
            return firstOperand + secondOperand;
          case '-':
            return firstOperand - secondOperand;
          case '*':
            return firstOperand * secondOperand;
          case '÷':
            return firstOperand / secondOperand;
          default:
            return secondOperand;
        }
      },
      // 计算结果
      calculate() {
        // 如果未输入第二个操作数,直接返回,不执行计算
        if (this.operator && this.waitingForSecondOperand) {
          return;
        }
        if (this.operator) {
          const inputValue = parseFloat(this.displayValue);
          const secondOperand = this.waitingForSecondOperand ? this.firstOperand : inputValue; // 如果没有第二个操作数,则使用第一个操作数
 
          const result = this.performCalculation(this.firstOperand, secondOperand, this.operator);
 
          // 完整地记录本次运算过程
          this.currentExpression = `${this.firstOperand} ${this.operator} ${secondOperand} = ${result}`;
 
          this.displayValue = String(result);
          this.firstOperand = result;
          this.operator = null;
          this.waitingForSecondOperand = false;
        }
      },
      // 清除
      clear() {
        this.displayValue = '0';
        this.firstOperand = null;
        this.operator = null;
        this.waitingForSecondOperand = false;
        this.currentExpression = ''; // 清空当前运算过程
      },
      // 删除最后一个输入的字符
      deleteLast() {
        this.displayValue = this.displayValue.length > 1 ? this.displayValue.slice(0, -1) : '0';
        this.updateExpression();
      },
      // 改变符号
      toggleSign() {
        this.displayValue = String(parseFloat(this.displayValue) * -1);
        this.updateExpression();
      },
      // 处理百分比
      inputPercent() {
        this.displayValue = String(parseFloat(this.displayValue) / 100);
        this.updateExpression();
      },
      // 更新当前运算过程的显示内容
      updateExpression() {
        if (this.firstOperand !== null && this.operator) {
          // 如果还未输入第二个操作数,不显示 displayValue
          this.currentExpression = this.waitingForSecondOperand ?
            `${this.firstOperand} ${this.operator}` :
            `${this.firstOperand} ${this.operator} ${this.displayValue}`;
        } else {
          this.currentExpression = this.displayValue;
        }
        console.log('this.currentExpression', this.currentExpression)
      }
    }
  };
</script>
 
<style scoped>
  .calculator {
    width: 400px;
    margin: 0 auto;
    padding: 20px;
    background-color: #f1f1f1;
    border-radius: 10px;
    box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
  }
 
  .expression {
    min-height: 30px;
    color: #888;
    text-align: right;
    font-size: 16px;
    margin-bottom: 5px;
  }
 
  .display {
    width: 100%;
    min-height: 60px;
    background-color: #333;
    color: white;
    text-align: right;
    padding: 10px;
    font-size: 24px;
    border-radius: 5px;
    margin-bottom: 10px;
    word-wrap: break-word;
  }
 
  .buttons {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 10px;
  }
 
  button {
    width: 100%;
    font-size: 18px;
    border-radius: 5px;
    background-color: #fff;
    border: 1px solid #ccc;
  }
 
  .zero {
    grid-column: span 2;
  }
 
  >>>.el-button+.el-button {
    margin-left: 0;
  }
</style>

在项目中引用:

import Calculator from '@/components/common/calculator'
 
export default {
    components:{
        Calculator
    },
}

使用标签即可:

<Calculator></Calculator>

以上就是vue自定义实现计算器组件(附完整代码)的详细内容,更多关于Vue计算器的资料请关注脚本之家其它相关文章!

相关文章

  • Vue3+El-Plus实现表格行拖拽功能完整代码

    Vue3+El-Plus实现表格行拖拽功能完整代码

    在vue3+elementPlus网站开发中,详细完成el-table表格的鼠标拖拽/拖曳/拖动排序,下面这篇文章主要给大家介绍了关于Vue3+El-Plus实现表格行拖拽功能的相关资料,需要的朋友可以参考下
    2024-05-05
  • Vue.js轮播图走马灯代码实例(全)

    Vue.js轮播图走马灯代码实例(全)

    这篇文章主要介绍了Vue.js轮播图走马灯,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-05-05
  • Vue中通过minio上传文件的详细步骤

    Vue中通过minio上传文件的详细步骤

    最近项目中使用了minio作为静态资源管理服务,所以简单写一下如何通过minio来上传图片,下面这篇文章主要给大家介绍了关于Vue中通过minio上传文件的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-07-07
  • Vue如何实现多页面配置以及打包方式

    Vue如何实现多页面配置以及打包方式

    这篇文章主要介绍了Vue如何实现多页面配置以及打包方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-10-10
  • vue中监听返回键问题

    vue中监听返回键问题

    这篇文章主要介绍了解决vue中监听返回键问题,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-08-08
  • IntelliJ IDEA编辑器配置vue高亮显示

    IntelliJ IDEA编辑器配置vue高亮显示

    这篇文章主要为大家详细介绍了IntelliJ IDEA编辑器配置vue高亮显示,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-09-09
  • vue+elementUI下拉框回显问题及解决方式

    vue+elementUI下拉框回显问题及解决方式

    这篇文章主要介绍了vue+elementUI下拉框回显问题及解决方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-02-02
  • vue中组件传参的几种常用方法举例

    vue中组件传参的几种常用方法举例

    这篇文章主要给大家介绍了关于vue中组件传参的几种常用方法,Vue组件传参方也是面试最常考的内容,文中通过代码实例介绍的非常详细,对大家的学习或者工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-08-08
  • vue部署到线上为啥会出现404的原因分析及解决

    vue部署到线上为啥会出现404的原因分析及解决

    这篇文章主要介绍了vue部署到线上为啥会出现404的原因分析及解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-04-04
  • vue项目中使用vue-layer弹框插件的方法

    vue项目中使用vue-layer弹框插件的方法

    这篇文章主要介绍了vue项目中使用vue-layer弹框插件的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-03-03

最新评论