众所周知鸿蒙 JS 框架是非常轻量级的 MVVM 模式。通过使用和 Vue2 相似的属性劫持技术实现了响应式系统。
学习鸿蒙很长时间了,想写一个 demo 进行练练手,就选择开发这个仿苹果计算器程序。
先看效果图:
话不多说,上代码
hml:
<div class="container">
<div class="header">
<text class="{{outputClassName}}">{{output}}text>
div>
<div class="keyboard">
<block for="{{keyArr}}">
<div if="{{$item == '0'}}" class="zeroKeys" onclick="onclickNubmer({{$item}})">
<text>
{{$item}}
text>
div>
<div elif="{{$item == 'AC' || $item == '+/-' || $item == '%'}}" class="operatorKeys-top" onclick="onclickOper({{$item}})">
<text>
{{$item}}
text>
div>
<div elif="{{$item == '÷' || $item == '×' || $item == '-' || $item == '+' || $item == '='}}" class="operatorKeys-right" onclick="onclickOper({{$item}})">
<text>
{{$item}}
text>
div>
<div else class="keys keys-nubmer" onclick="onclickNubmer({{$item}})">
<text>
{{$item}}
text>
div>
block>
div>
div>
css:
.container {
flex-direction: column;
background-color: #010101;
height:100%;
width:100%;
}
.header{
height:36%;
width:100%;
align-items: flex-end;
padding:2px 20px 2px 10px;
}
.keyboard{
height:64%;
width:100%;
padding:2px 10px;
flex-wrap: wrap;
}
.outputText,.outputTextSmall{
width:100%;
height:100px;
color:#FFFFFF;
text-align: end;
}
.outputText{
font-size:80px;
}
.outputTextSmall{
font-size:58px;
}
.keys,.zeroKeys,.operatorKeys-top,.operatorKeys-right{
width:74px;
height:74px;
justify-content: center;
align-items: center;
border-radius:74px;
margin:10px 5px;
}
.keys-nubmer,.zeroKeys{
background-color:#333333;
}
.zeroKeys{
width:158px;
}
.operatorKeys-top{
background-color: #a4a4a4;
}
.operatorKeys-right{
background-color: #f79f31;
}
.keys:active,.zeroKeys:active{
background-color: #737373;
}
.keys text,.zeroKeys text,.operatorKeys-right text{
font-size:42px;
color: #FFFFFF;
}
.operatorKeys-top text{
font-size:36px;
color: #010101;
}
.operatorKeys-top:active{
background-color: #d9d9d9;
}
.operatorKeys-right:active{
background-color: #f5c891;
}
js:
import {math} from "../../common/js/utils.js";
export default {
data: {
output:"0",
outputClassName:"outputText",
cache:[],//记录输入内容
keyArr:["AC","+/-","%","÷","7","8","9","×","4","5","6","-","1","2","3","+","0",".","="],
reOper:"",//记录点击的运算符
reStr1:"",//记录第一次输入内容
reStr2:"",//记录点击运算符后的内容
bool:false//防止第二次输入内容时内容清空
},
onInit(){
this.$watch("output","watchOutPut")
},
onclickOper(item){
if(item == "AC"){
this.clearComput();
} else if(item == "+" || item == "-" || item == "×" || item == "÷"){
this.reOper = item;
this.reStr1 = this.output;
if(this.cache.length > 0){
this.startCompute();
}
this.cache.push(this.reStr1);
} else if(item == "+/-"){
this.output = "-"+this.output;
} else if(item == "%"){
this.output = math.accDiv(this.output,100);
} else if(item == "="){
this.reStr2 = this.output;
this.cache.push(this.reStr2);
this.startCompute();
}
},
onclickNubmer(item){
if(this.cache.length > 0 && !this.bool){
this.output = "0";
this.bool = true;
}
if(this.output == "0" && item != "."){
this.output = item;
} else if(item == "."){
if(this.output.indexOf(".") == -1){
if(this.output == "0"){
this.output = "0."
} else {
this.output += item;
}
}
} else {
if(this.output.length < 10){
this.output += item;
}
}
},
watchOutPut(nVal){
if(nVal.length > 7 && nVal.length< 10){
this.outputClassName = "outputTextSmall";
} else {
this.outputClassName = "outputText";
}
},
startCompute(){
switch (this.reOper) {
case "+":
this.output = math.accAdd(this.reStr1,this.reStr2);
this.reStr1 = this.output;
break;
case "-":
this.output = math.accSub(this.reStr1,this.reStr2);
this.reStr1 = this.output;
break;
case "×":
this.output = math.accMul(this.reStr1,this.reStr2);
this.reStr1 = this.output;
break;
case "÷":
this.output = math.accDiv(this.reStr1,this.reStr2);
this.reStr1 = this.output;
break;
default:
break;
}
},
clearComput(){
this.output = "0";
this.reOper = "";
this.reStr1 = "";
this.reStr2 = "";
this.cache = [];
this.bool = false;
}
}
utils.js:
class MathCalss {
//js精准除法函数
accDiv(arg1, arg2){
let t1 = 0,
t2 = 0,
r1,
r2;
try {
t1 = arg1.toString().split('.')[1].length;
} catch (e) {}
try {
t2 = arg2.toString().split('.')[1].length;
} catch (e) {}
r1 = Number(arg1.toString().replace('.', ''));
r2 = Number(arg2.toString().replace('.', ''));
return (r1 / r2) * Math.pow(10, t2 - t1);
}
//js精准加法函数
accAdd(arg1, arg2) {
var r1, r2, m, c;
try {
r1 = arg1.toString().split(".")[1].length;
}
catch (e) {
r1 = 0;
}
try {
r2 = arg2.toString().split(".")[1].length;
}
catch (e) {
r2 = 0;
}
c = Math.abs(r1 - r2);
m = Math.pow(10, Math.max(r1, r2));
if (c > 0) {
var cm = Math.pow(10, c);
if (r1 > r2) {
arg1 = Number(arg1.toString().replace(".", ""));
arg2 = Number(arg2.toString().replace(".", "")) * cm;
} else {
arg1 = Number(arg1.toString().replace(".", "")) * cm;
arg2 = Number(arg2.toString().replace(".", ""));
}
} else {
arg1 = Number(arg1.toString().replace(".", ""));
arg2 = Number(arg2.toString().replace(".", ""));
}
return (arg1 + arg2) / m;
}
//js精准减法函数
accSub(arg1, arg2) {
let r1, r2, m, n;
try {
r1 = arg1.toString().split('.')[1].length;
} catch (e) {
r1 = 0;
}
try {
r2 = arg2.toString().split('.')[1].length;
} catch (e) {
r2 = 0;
}
m = Math.pow(10, Math.max(r1, r2));
//动态控制精度长度
n = r1 >= r2 ? r1 : r2;
return (arg1 * m - arg2 * m) / m;
}
//js精准乘法函数
accMul(arg1, arg2) {
var m = 0, s1 = arg1.toString(), s2 = arg2.toString();
try {
m += s1.split(".")[1].length;
}
catch (e) {
}
try {
m += s2.split(".")[1].length;
}
catch (e) {
}
return Number(s1.replace(".", "")) * Number(s2.replace(".", "")) / Math.pow(10, m);
}
}
export var math = new MathCalss();
为了解决浮点数计算失准问题,我使用一些解决计算失准的函数可供大家参考。
全部0条评论
快来发表一下你的评论吧 !