目前实现的功能: 1.X后退一步,C全部清除 2.支持小数点 3.一次运算输出一个结果,再次运算是与上一次的结果
核心代码:
<template>
<div
class="calculator_wrap"
:style="{ color: expenseFontColor }"
@click="clickKeyboard"
>
<img :src="expenseKeyboardBg" alt="" v-if="expenseKeyboardBg" />
<img src="../../assets/images/home/skin/skin5-3/bg.jpg" alt="" v-else />
<div class="content">
<div class="calculator_temp">
<span>{{ temp ? temp : "0.00" }}</span>
</div>
<div
v-for="(item, index) in arr"
:key="index"
class="calculator_row"
>
<div
v-for="(item2, index2) in item"
:key="index2"
class="calculator_col"
:style="{ 'background-color': item2.color }"
@click="handleCalculator"
>
<div>{{ item2.value }}</div>
</div>
</div>
</div>
</div>
</template>
<script>
import { mapActions, mapState } from "vuex";
export default {
props: {
money: {
type: Number,
default: 0,
},
show: {
type: Boolean,
default: false,
},
currency: {
type: String,
default: "CNY",
},
clickable: {
type: Boolean,
default: true,
},
},
computed: {
...mapState({
expenseKeyboardBg: (state) =>
state.systemSettings.expenseKeyboardBg,
expenseKeyboardSound: (state) =>
state.systemSettings.expenseKeyboardSound,
expenseFontColor: (state) =>
state.systemSettings.expenseFontColor,
}),
},
data() {
return {
result: 0,
temp: "",
operator: "",
arr: [
[
{ value: "7" },
{ value: "8" },
{ value: "9" },
{ value: "+" },
{ value: "X" },
],
[
{ value: "4" },
{ value: "5" },
{ value: "6" },
{ value: "-" },
{ value: "C" },
],
[
{ value: "1" },
{ value: "2" },
{ value: "3" },
{ value: "*" },
{ value: "取消", color: "yellow" },
],
[
{ value: "货币", color: "green" },
{ value: "0" },
{ value: "." },
{ value: "/" },
{ value: "完成", color: "yellow" },
],
],
};
},
methods: {
...mapActions({
asyncPlaySound: "keyboard/asyncPlaySound",
}),
handleCalculator(e) {
if (!this.clickable) {
return;
}
const choice = e.target.innerText;
switch (true) {
case /^X$/.test(choice):
this.temp = this.temp.slice(0, this.temp.length - 1) || "";
break;
case /^C$/.test(choice):
this.temp = "";
break;
case /取消/.test(choice):
this.$emit("handleCancel");
break;
case /完成/.test(choice):
if (this.temp !== "") {
if(isNaN(Number(this.temp))){
this.temp = this.temp.slice(0, this.temp.length - 1);
}
this.temp = Number(this.temp).toFixed(2);
} else {
this.temp = "0.00";
}
this.$emit("handleConfirm", this.temp);
break;
case /^货币/.test(choice):
this.chooseCurrency();
break;
case /^=/.test(choice):
this.temp = eval(this.temp).toFixed(2);
this.changeCompleteBtn("完成")
break;
default:
if (!this.checkValid(choice)) {
return;
}
//要先输入数字
if (this.temp === "" &&["+", "-", "*", "/"].indexOf(choice) != -1) {
return;
}
if (
this.arr[3][4].value === "=" &&
["+", "-", "*", "/"].indexOf(choice) != -1
) {
this.temp = eval(this.temp).toFixed(2);
}
this.temp += choice;
break;
}
},
chooseCurrency() {
this.$emit("showMoneyType");
},
changeCompleteBtn(str) {
this.arr[3][4].value = str;
},
checkValid(choice) {
//1. 不允许输入3.00..
if (/\d+\.\d\d$/.test(this.temp) && choice == ".") {
return false;
}
//2. 限制用户输入的是两位小数
if (
/\d+\.\d\d$/.test(this.temp) &&
choice >= "0" &&
choice <= "9"
) {
return false;
}
//3. 不允许输入两个操作符
if (
["+", "-", "*", "/"].indexOf(this.temp[this.temp.length - 1]) != -1 &&
["+", "-", "*", "/"].indexOf(choice) != -1
) {
this.temp = this.temp.substring(0, this.temp.length - 1);
}
return true;
},
//按下键盘上的某一个键
clickKeyboard() {
if (this.expenseKeyboardSound) {
this.asyncPlaySound();
}
},
},
watch: {
temp: function (val) {
if (/(\d+\.?)[+\-*/](\d+\.?)/.test(val)) {
this.changeCompleteBtn("=");
}else{
this.changeCompleteBtn("完成");
}
},
show: function (newVal, oldVal) {
if (newVal && !oldVal) {
if (this.temp == "0.00") {
this.temp = "";
}
}
},
currency: function (val) {
this.arr[3][0].value = "货币" + val;
},
},
created() {
this.arr[3][0].value = "货币" + this.currency;
},
};
</script>
<style scoped>
.calculator_wrap {
width: 100%;
height: 4rem;
padding-bottom: 0.15rem;
position: relative;
}
.calculator_wrap .content{
position: absolute;
top: 0;
left: 0;
z-index: 10;
width: 100%;
height: 100%;
}
.calculator_wrap img {
position: absolute;
opacity: 0.5;
top: 0;
left: 0;
z-index: 9;
width: 100%;
height: 100%;
}
.calculator_wrap .calculator_row {
display: flex;
}
.calculator_wrap .calculator_col {
width: 20%;
height: 0.8rem;
border: 0.04rem solid #c7c7c7;
border-radius: 0.1rem;
display: flex;
align-items: center;
justify-content: center;
}
.calculator_wrap .calculator_temp {
height: 0.8rem;
text-align: right;
line-height: 0.8rem;
border-bottom: 0.02rem solid #c7c7c7;
margin-bottom: 0.01rem;
}
.calculator_wrap .calculator_temp span {
display: inline-block;
margin-right: 0.2rem;
font-size: 0.4rem;
}
</style>
事件:
handleConfirm - 确认键盘输入
handleCancel - 取消键盘输入
handleMoneyType - 打开币种选择
props:
money - 初始金额
show - 键盘显示
currency - 币种简称,如CNY
clickable - 键盘是否可点击