Featured image of post vue 计算器 script setup

vue 计算器 script setup

2022-12-01-vue_calculator

作者:134333.xyz/

  • 逻辑链

    • 输入 数字:设置 isStarted = true
      • 代表后续可以输入 加减乘除小数点
    • 输入 加减乘除:设置 isOperatorAdded = true
      • 代表后续不能输入 加减乘除
    • 输入 小数点:设置 isDecimalAdded = true
      • 代表后续不能输入 小数点
  • append()

    • 1、第一个 if(),判断一开始输入的内容
      • 输入 数字/小数点 时,是 . 就在末尾追加,是 数字 就替换
    • 2、第二个 if(),小数点不能连续输入
      • 输入 小数点 时,判断 isDecimalAdded 变量,为 true 时返回空,为 false 时设置isOperatorAddedisDecimalAddedtrue,代表接下来不能出现 加减乘除小数点
    • 3、第三个 if(),输入 加减乘除
      • 判断 isOperatorAdded 变量后续是否可以继续输入符号。
// 点击 数字和加减乘除 时
let append = (character) => {
  // 1. Start
  // 输入 '.' 就在末尾添加, 否则就替换成数字
  if (equation.value === "0" && !isOperator(character)) {
    if (character === ".") {
      equation.value += "" + character;
      isDecimalAdded.value = true;
    } else {
      // '' 作用, 转换成 string
      equation.value = "" + character;
    }

    // 已经存在数字
    isStarted.value = true;
    return;
  }

  // 2. 小数点不能连续输入
  if (!isOperator(character)) {
    if (character === "." && isDecimalAdded.value) {
      return;
    } else if (character === ".") {
      isDecimalAdded.value = true;
      isOperatorAdded.value = true;
    } else {
      isOperatorAdded.value = false;
    }

    equation.value += "" + character;
  }

  // 3. 输入运算符号
  if (isOperator(character) && !isOperatorAdded.value) {
    equation.value += "" + character;
    isDecimalAdded.value = false;
    isOperatorAdded.value = true;
  }
};

index.vue

<template>
  <div class="calculator">
    <div class="result" style="grid-area: result">{{ equation }}</div>

    <button style="grid-area: ac" @click="clear">AC</button>
    <button style="grid-area: plus-minus" @click="calculateToggle">±</button>
    <button style="grid-area: percent" @click="calculatePercentage">%</button>
    <button style="grid-area: add" @click="append('+')">+</button>
    <button style="grid-area: subtract" @click="append('-')">-</button>
    <button style="grid-area: multiply" @click="append('×')">×</button>
    <button style="grid-area: divide" @click="append('÷')">÷</button>
    <button style="grid-area: equal" @click="calculate">=</button>

    <button style="grid-area: number-1" @click="append(1)">1</button>
    <button style="grid-area: number-2" @click="append(2)">2</button>
    <button style="grid-area: number-3" @click="append(3)">3</button>
    <button style="grid-area: number-4" @click="append(4)">4</button>
    <button style="grid-area: number-5" @click="append(5)">5</button>
    <button style="grid-area: number-6" @click="append(6)">6</button>
    <button style="grid-area: number-7" @click="append(7)">7</button>
    <button style="grid-area: number-8" @click="append(8)">8</button>
    <button style="grid-area: number-9" @click="append(9)">9</button>
    <button style="grid-area: number-0" @click="append(0)">0</button>

    <button style="grid-area: dot" @click="append('.')">.</button>
  </div>
</template>

<script setup>
  import { ref } from "vue";
  // 输出
  let equation = ref("0");

  // 判断是否已输入 小数点
  // 为 true 时代表下个 '输入值' 不能为小数点
  let isDecimalAdded = ref(false);
  // 判断是否已输入 加减乘除
  let isOperatorAdded = ref(false);
  // 判断是否已输入 数字
  let isStarted = ref(false);

  // character 是输入操作!
  // 判断 character 是否是 加/减/乘/除
  let isOperator = (character) => {
    return ["+", "-", "×", "÷"].indexOf(character) > -1;
  };

  // 点击 数字和加减乘除 时
  let append = (character) => {
    // 1. Start
    // 输入 '.' 就在末尾添加, 否则就替换成数字
    if (equation.value === "0" && !isOperator(character)) {
      if (character === ".") {
        equation.value += "" + character;
        isDecimalAdded.value = true;
      } else {
        // '' 作用, 转换成 string
        equation.value = "" + character;
      }

      // 已经存在数字
      isStarted.value = true;
      return;
    }

    // 2. 小数点不能连续输入
    if (!isOperator(character)) {
      if (character === "." && isDecimalAdded.value) {
        return;
      } else if (character === ".") {
        isDecimalAdded.value = true;
        isOperatorAdded.value = true;
      } else {
        isOperatorAdded.value = false;
      }

      equation.value += "" + character;
    }

    // 3. 输入运算符号
    if (isOperator(character) && !isOperatorAdded.value) {
      equation.value += "" + character;
      isDecimalAdded.value = false;
      isOperatorAdded.value = true;
    }
  };

  // 点击 '='
  let calculate = () => {
    let result = equation.value
      .replace(new RegExp("×", "g"), "*")
      .replace(new RegExp("÷", "g"), "/");
    // 限制长度为 9
    equation.value = parseFloat(eval(result).toFixed(9)).toString();
    isDecimalAdded.value = false;
    isOperatorAdded.value = false;
  };

  // 点击 '+/-'
  let calculateToggle = () => {
    if (isOperatorAdded.value || !isStarted.value) {
      return;
    }

    equation.value = equation.value + "* -1";
    calculate();
  };

  // 点击 '%'
  let calculatePercentage = () => {
    if (isOperatorAdded.value || !isStarted.value) {
      return;
    }

    equation.value = equation.value + "* 0.01";
    calculate();
  };

  // 点击 'AC'
  let clear = () => {
    equation.value = "0";
    isDecimalAdded.value = false;
    isOperatorAdded.value = false;
    isStarted.value = false;
  };
</script>

<style lang="scss">
  body {
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: 100vh;
    background-color: #eee;
  }

  .calculator {
    --button-width: 80px;
    --button-height: 80px;

    display: grid;
    grid-template-areas:
      "result result result result"
      "ac plus-minus percent divide"
      "number-7 number-8 number-9 multiply"
      "number-4 number-5 number-6 subtract"
      "number-1 number-2 number-3 add"
      "number-0 number-0 dot equal";
    grid-template-columns: repeat(4, var(--button-width));
    grid-template-rows: repeat(6, var(--button-height));

    box-shadow: -8px -8px 16px -10px rgba(255, 255, 255, 1), 8px 8px 16px -10px
        rgba(0, 0, 0, 0.15);
    padding: 24px;
    border-radius: 20px;
  }

  .calculator button {
    display: block;

    margin: 8px;
    padding: 0;

    border: 0;
    border-radius: calc(var(--button-height) / 2);

    outline: none;

    font-size: 24px;
    font-family: Helvetica;
    font-weight: normal;

    color: #333;
    background: linear-gradient(
      135deg,
      rgba(230, 230, 230, 1) 0%,
      rgba(246, 246, 246, 1) 100%
    );
    box-shadow: -4px -4px 10px -8px rgba(255, 255, 255, 1), 4px 4px 10px -8px
        rgba(0, 0, 0, 0.3);
  }

  .calculator button:nth-child(-n + 9) {
    color: #ff7433;
  }

  .calculator button:active {
    box-shadow: -4px -4px 10px -8px rgba(255, 255, 255, 1) inset, 4px 4px
        10px -8px rgba(0, 0, 0, 0.3) inset;
  }

  .result {
    padding: 0 20px;
    color: #333;

    text-align: right;
    line-height: var(--button-height);

    font-size: 48px;
    font-family: Helvetica;
  }
</style>
Licensed under CC BY-NC-SA 4.0
本博客已稳定运行
发表了53篇文章 · 总计28.17k字
使用 Hugo 构建
主题 StackJimmy 设计