作者:134333.xyz/
逻辑链
- 输入
数字
:设置isStarted = true
- 代表后续可以输入 加减乘除 和 小数点。
- 输入
加减乘除
:设置isOperatorAdded = true
- 代表后续不能输入 加减乘除
- 输入
小数点
:设置isDecimalAdded = true
- 代表后续不能输入 小数点
- 输入
append()
- 1、第一个
if()
,判断一开始输入的内容- 输入
数字/小数点
时,是.
就在末尾追加,是数字
就替换
- 输入
- 2、第二个
if()
,小数点不能连续输入- 输入
小数点
时,判断isDecimalAdded
变量,为true
时返回空,为false
时设置isOperatorAdded
和isDecimalAdded
为true
,代表接下来不能出现 加减乘除 和 小数点。
- 输入
- 3、第三个
if()
,输入 加减乘除 时- 判断
isOperatorAdded
变量后续是否可以继续输入符号。
- 判断
- 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;
}
};
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>