vue自定义计算器组件

时间:2024-11-20 07:08:23

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

创建计算器组件文件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>