javascript - 是什么原因导致此 Vue 计算器应用程序中的模板变量更新失败?

标签 javascript vue.js vuejs3

我正在使用 Vue 3 开发一个小型计算器应用程序。在显示部分,我显示算术运算的结果和按下的按键的“记录”:

<div class="display">
  <div class="track">
    {{track == '' ? ''  :  track + '=' }}
  </div>
  <div class="result">
    {{currentVal || 0}}
  </div>
</div>

我使用 showOperationsTrack(clickedVal) 方法来显示上述“记录”:

const calculatorApp = {
  data() {
    return {
      track: "",
      currentVal: "",
      previousVal: null,
      operation: null,
      isOperatorClicked: false,
      isResultDisplayed: false
    };
  },
  methods: {
    showOperationsTrack(clickedVal) {
      if (!this.isResultDisplayed) {
        this.track = `${this.track}${clickedVal}`;
      } else {
        this.currentVal = "";
      }
    },
    appendClicked(clickedVal) {
      if (this.isOperatorClicked) {
        this.currentVal = "";
        this.isOperatorClicked = false;
      }

      if (this.isResultDisplayed) {
        this.currentVal = "";
        this.isResultDisplayed = false;
      }

      this.currentVal = `${this.currentVal}${clickedVal}`;

      this.showOperationsTrack(clickedVal);
    },
    appendDot() {
      if (this.currentVal.indexOf(".") === -1) {
        this.appendClicked(".");
      }
    },
    setPreviousVal() {
      this.previousVal = this.currentVal;
      this.isOperatorClicked = true;
    },
    add(clickedVal) {
      this.operation = (a, b) => a + b;
      this.setPreviousVal();
      this.showOperationsTrack(clickedVal);
    },
    subtract(clickedVal) {
      this.operation = (a, b) => a - b;
      this.setPreviousVal();
      this.showOperationsTrack(clickedVal);
    },
    multiply(clickedVal) {
      this.operation = (a, b) => a * b;
      this.setPreviousVal();
      this.showOperationsTrack(clickedVal);
    },
    divide(clickedVal) {
      this.operation = (a, b) => a / b;
      this.setPreviousVal();
      this.showOperationsTrack(clickedVal);
    },
    equals() {
      this.currentVal = this.operation(
        parseFloat(this.previousVal),
        parseFloat(this.currentVal)
      );
      this.isResultDisplayed = true;
      this.previousVal = null;
    },
    clearDisplay() {
      this.currentVal = "";
      this.track = "";
    }
  }
};
Vue.createApp(calculatorApp).mount("#myCalculator");
body {
  padding: 0;
  margin: 0;
}

body * {
  box-sizing: border-box;
}

.container {
  min-height: 100vh;
}

.calculator {
  font-family: Montserrat, sans-serif;
  width: 100%;
  max-width: 360px;
  min-width: 300px;
  margin: 10px auto;
  padding: 36px;
  background: #efefef;
  border-radius: 10px;
}

.display {
  position: relative;
  font-weight: bold;
  display: flex;
  flex-direction: column;
  background: #c3c3c3;
  border-radius: 10px;
  margin-bottom: 34px;
  padding: 10px 20px;
}

.result,
.track {
  display: flex;
  justify-content: flex-end;
}

.result {
  margin-top: 3px;
  font-size: 48px;
}

.track {
  position: absolute;
  top: 5px;
  left: 20px;
  right: 20px;
  font-size: 12px;
}

.buttons-container ol {
  list-style-type: none;
  padding: 0;
  margin: 0;
  color: #242424;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  column-gap: 10px;
  row-gap: 10px;
}

.buttons-container li,
.buttons-container .clear {
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 36px;
  height: 60px;
  font-weight: 600;
  background: #e7e7e7;
  border-radius: 7px;
  border: 1px solid rgba(0, 0, 0, 0.1);
  cursor: pointer;
}

.buttons-container li {
  width: 60px;
}

.buttons-container .clear {
  margin-top: 10px;
  text-transform: uppercase;
  font-weight: 600;
}

.buttons-container .orange {
  background: #ff9800;
  color: #fff;
}

.buttons-container .active {
  transform: translate(1px, -1px);
}
<link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@400;500,600&display=swap" rel="stylesheet">
<script src="https://unpkg.com/vue@next"></script>

<div class="container">
  <div class="calculator" id="myCalculator">
    <div class="display">
      <div class="track">
        {{track == '' ? ''  :  track + '=' }}
      </div>
      <div class="result">
        {{currentVal || 0}}
      </div>
    </div>
    <div class="buttons-container">
      <ol>
        <li @click="appendClicked('7')">7</li>
        <li @click="appendClicked('8')">8</li>
        <li @click="appendClicked('9')">9</li>
        <li @click="divide('&divide;')">&divide;</li>
        <li @click="appendClicked('4')">4</li>
        <li @click="appendClicked('5')">5</li>
        <li @click="appendClicked('6')">6</li>
        <li @click="multiply('&times;')">&times;</li>
        <li @click="appendClicked('1')">1</li>
        <li @click="appendClicked('2')">2</li>
        <li @click="appendClicked('3')">3</li>
        <li @click="subtract('-')">-</li>
        <li @click="appendClicked('0')">0</li>
        <li @click="appendDot('.')">&middot;</li>
        <li @click="add('+')">+</li>
        <li @click="equals" class="orange">=</li>
      </ol>
      <div @click="clearDisplay" class="clear orange">Clear</div>
    </div>
  </div>
</div>

问题

由于我未能发现的原因,尽管在每次新计算开始时结果都正确设置为 0,但操作记录并未设置为 ''.

问题

  1. 是什么原因导致此问题?
  2. 什么是可靠的解决方案?

最佳答案

当按下 equal 时,您可以清除数据属性 track

const calculatorApp = {
  data() {
    return {
      track: "",
      currentVal: "",
      previousVal: null,
      operation: null,
      isOperatorClicked: false,
      isResultDisplayed: false,
      busy: false
    };
  },
  methods: {
    showOperationsTrack(clickedVal) {
      if (!this.isResultDisplayed) {
        this.track = `${this.track}${clickedVal}`;
      } else {
        this.currentVal = "";
      }
    },
    appendClicked(clickedVal) {
      if(this.busy === true) {
      this.clearDisplay()
      this.busy = false
      }
      if (this.isOperatorClicked) {
        this.currentVal = "";
        this.isOperatorClicked = false;
      }

      if (this.isResultDisplayed) {
        this.currentVal = "";
        this.isResultDisplayed = false;
      }

      this.currentVal = `${this.currentVal}${clickedVal}`;

      this.showOperationsTrack(clickedVal);
    },
    appendDot() {
      if (this.currentVal.indexOf(".") === -1) {
        this.appendClicked(".");
      }
    },
    setPreviousVal() {
      this.previousVal = this.currentVal;
      this.isOperatorClicked = true;
    },
    add(clickedVal) {
      this.operation = (a, b) => a + b;
      this.setPreviousVal();
      this.showOperationsTrack(clickedVal);
    },
    subtract(clickedVal) {
      this.operation = (a, b) => a - b;
      this.setPreviousVal();
      this.showOperationsTrack(clickedVal);
    },
    multiply(clickedVal) {
      this.operation = (a, b) => a * b;
      this.setPreviousVal();
      this.showOperationsTrack(clickedVal);
    },
    divide(clickedVal) {
      this.operation = (a, b) => a / b;
      this.setPreviousVal();
      this.showOperationsTrack(clickedVal);
    },
    equals() {
      this.currentVal = this.operation(
        parseFloat(this.previousVal),
        parseFloat(this.currentVal)
      );
      this.isResultDisplayed = true;
      this.previousVal = null;
      this.busy = true
    },
    clearDisplay() {
      this.currentVal = "";
      this.track = "";
    }
  }
};
Vue.createApp(calculatorApp).mount("#myCalculator");
body {
  padding: 0;
  margin: 0;
}

body * {
  box-sizing: border-box;
}

.container {
  min-height: 100vh;
}

.calculator {
  font-family: Montserrat, sans-serif;
  width: 100%;
  max-width: 360px;
  min-width: 300px;
  margin: 10px auto;
  padding: 36px;
  background: #efefef;
  border-radius: 10px;
}

.display {
  position: relative;
  font-weight: bold;
  display: flex;
  flex-direction: column;
  background: #c3c3c3;
  border-radius: 10px;
  margin-bottom: 34px;
  padding: 10px 20px;
}

.result,
.track {
  display: flex;
  justify-content: flex-end;
}

.result {
  margin-top: 3px;
  font-size: 48px;
}

.track {
  position: absolute;
  top: 5px;
  left: 20px;
  right: 20px;
  font-size: 12px;
}

.buttons-container ol {
  list-style-type: none;
  padding: 0;
  margin: 0;
  color: #242424;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  column-gap: 10px;
  row-gap: 10px;
}

.buttons-container li,
.buttons-container .clear {
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 36px;
  height: 60px;
  font-weight: 600;
  background: #e7e7e7;
  border-radius: 7px;
  border: 1px solid rgba(0, 0, 0, 0.1);
  cursor: pointer;
}

.buttons-container li {
  width: 60px;
}

.buttons-container .clear {
  margin-top: 10px;
  text-transform: uppercase;
  font-weight: 600;
}

.buttons-container .orange {
  background: #ff9800;
  color: #fff;
}

.buttons-container .active {
  transform: translate(1px, -1px);
}
<link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@400;500,600&display=swap" rel="stylesheet">
<script src="https://unpkg.com/vue@next"></script>

<div class="container">
  <div class="calculator" id="myCalculator">
    <div class="display">
      <div class="track">
        {{track == '' ? ''  :  track + '=' }}
      </div>
      <div class="result">
        {{currentVal || 0}}
      </div>
    </div>
    <div class="buttons-container">
      <ol>
        <li @click="appendClicked('7')">7</li>
        <li @click="appendClicked('8')">8</li>
        <li @click="appendClicked('9')">9</li>
        <li @click="divide('&divide;')">&divide;</li>
        <li @click="appendClicked('4')">4</li>
        <li @click="appendClicked('5')">5</li>
        <li @click="appendClicked('6')">6</li>
        <li @click="multiply('&times;')">&times;</li>
        <li @click="appendClicked('1')">1</li>
        <li @click="appendClicked('2')">2</li>
        <li @click="appendClicked('3')">3</li>
        <li @click="subtract('-')">-</li>
        <li @click="appendClicked('0')">0</li>
        <li @click="appendDot('.')">&middot;</li>
        <li @click="add('+')">+</li>
        <li @click="equals" class="orange">=</li>
      </ol>
      <div @click="clearDisplay" class="clear orange">Clear</div>
    </div>
  </div>
</div>

关于javascript - 是什么原因导致此 Vue 计算器应用程序中的模板变量更新失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70595910/

相关文章:

javascript - JavaScript 数字是否遵循 IEEE 754 double ?

javascript - Firefox 中的突出显示速度缓慢

javascript - 按钮背景颜色不起作用

javascript - 只打开一个 Accordion 面板 vue.js/bootstrap vue

vue.js - 基于路由动态插入 CSS 类到导航栏

javascript - 组件函数仅适用于第一个组件 Vue.js

javascript - 获取网站词频计数的最佳方法?还是网站的一部分?

vue.js - 如何以编程方式添加 Vue 3 组件?

javascript - Vue双向数据绑定(bind)到深层嵌套数据对象

javascript - Vue 3 – 淡入淡出过渡