开发一个鸿蒙版仿苹果计算器教程.附代码

描述

众所周知鸿蒙 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(10Math.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(10Math.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();

 

为了解决浮点数计算失准问题,我使用一些解决计算失准的函数可供大家参考。
编辑:jq
打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分