微信小程序之计算器

在日常生活中,计算器是人们广泛使用的工具,可以帮助我们快速且方便地计算金额、成本、利润等。下面将会讲解如何开发一个"计算器"微信小程序。

一、开发思路

1、界面和功能

"计算器"微信小程序的页面效果如图所示

在计算器中可以进行整数和小数的加(+)、减(-)、乘(×)、除(÷)运算。"C"按钮为清除按钮,表示将输入的数字全部清空;"DEL"按钮为删除按钮,表示删除前面输入的一个数字;"+/-"按钮为正负号切换按钮,用于实现正负数切换;"."按钮为小数点按钮,表示在计算过程中可以输入小数进行计算;"="按钮为等号按钮,表示对输入的数字进行计算。

2、计算器设计数学原理

此计算器本本质是对数学表达式的求解,例如 Z=X+Y,其中,X,Y为两个自变量,Z为因变量,主要设计思路为千先输入X,Y,和"+"号,再输入"="号计算结果并显示 。由此可知,基本操作为:

(1)输入第一个数字(存储为变量num1并显示)。

(2)输入运算符(存储为num2并显示)。

(3)输入运算符(形成表达式并显示)。

(4)按下"="(计算结果并显 示)。

3. 设计主要思路

根据以上分析可知,处理逻辑主要编写以下三个函数

numBtn():处理函数三个数字按钮的事件处理函数

opBtn:运算符按钮的事件处理函数

execBtn():编写"="按钮的事件处理函数

设计三个标识用以标识用户的三种状态,其中,数字改变标识为真:

numChangeFlag : 数字改变标识,第一数字和第二数字切换标识,初始值为false

execflag: 执行状态标识,初始值为false

resultflag: 结果状态标识,初始值为false

具体的处理逻辑详见四处理逻辑

二、界面设计

据以上的开发思路,界面分为显示区和按钮区,其中显示区又分为数字显示区、公式显示区两部分,上下排列;按钮可分为数字按钮,运算符按钮,功能按钮三部分,按钮显示区按四行四列显示,其中"0"独占两个单元格。代码如下所示:

html 复制代码
<!--index.wxml-->
<navigation-bar title="计算器" back="{{false}}" color="black" background="#FFF"></navigation-bar>
<!--结果区域-->
<view class="result">
<view class="result-num">{{num}}</view>
<view class="result-sub">{{sub}}</view>
</view>
<!--按钮区域-->
<view class="btns">
<view>
<view hover-class="bg"  hover-stay-time="50"  bindtap="resetBtn">C</view>
<view hover-class="bg"  hover-stay-time="50"  bindtap="delBtn">DEL</view>
<view hover-class="bg"  hover-stay-time="50"  bindtap="negBtn">+/-</view>
<view hover-class="bg"  hover-stay-time="50"  bindtap="opBtn" data-val='×'>×</view>
</view>
<view>
    <view hover-class="bg" bindtap="numBtn" data-val="7">7</view>
    <view hover-class="bg" bindtap="numBtn" data-val="8">8</view>
    <view hover-class="bg" bindtap="numBtn" data-val="9">9</view>
    <view hover-class="bg" bindtap="opBtn" data-val="÷">÷</view>
  </view>
  <view>
    <view hover-class="bg" bindtap="numBtn" data-val="4">4</view>
    <view hover-class="bg" bindtap="numBtn" data-val="5">5</view>
    <view hover-class="bg" bindtap="numBtn" data-val="6">6</view>
    <view hover-class="bg" bindtap="opBtn" data-val="-">-</view>
  </view>
  <view>
    <view hover-class="bg" bindtap="numBtn" data-val="1">1</view>
    <view hover-class="bg" bindtap="numBtn" data-val="2">2</view>
    <view hover-class="bg" bindtap="numBtn" data-val="3">3</view>
    <view hover-class="bg" bindtap="opBtn" data-val="+">+</view>
  </view>
  <view>
    <view hover-class="bg" bindtap="numBtn" data-val="0">0</view>
    <view hover-class="bg" bindtap="dotBtn">.</view>
    <view hover-class="bg" bindtap="execBtn" data-val="=">=</view>
  </view>
</view>

界面布置总体上采用"flex"流式布局column方式,上下排列,按钮区以每四个按钮为一组,共分四组,同样采用flex的流式布局,具体css代码如下所示:

html 复制代码
​
/**index.wxss**/
page {
  display: flex;
  flex-direction: column;
  height: 100vh;
  color: #555;
}
.result {
   flex: 1;
   background: #f3fef6;
   position: relative;
}
.result-num {
    position: absolute;
    font-size: 15vw;
    bottom: 5vh;
    right: 3vw;
}
.result-sub{
font-size: 10vw;
position: absolute;
bottom: 1vh;
right: 3vw;
}

.btns {
flex: 1;
}

/* 按钮样式 */
.bg {
background: #eee;
}
.btns {
flex: 1;
display: flex;
flex-direction: column;
font-size: 64rpx;
border-top: 1rpx solid #ccc;
border-left: 1rpx solid #ccc;
}
.btns > view {
flex: 1;
display: flex;
}
.btns > view > view {
flex-basis: 25%;
border-right: 1rpx solid #ccc;
border-bottom: 1rpx solid #ccc;
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: center;
}
.btns > view:last-child > view:first-child {
flex-basis: 50%;
}

.btns > view:first-child > view:first-child {
color: #f00;
}

.btns > view > view:last-child {
color: #fc8e00;
}


​

三,知识储备

1、data-*自定义属性

data-*是微信小程序的自定义属性,由data-前缀加上自定义的属性名,自定义属性值表示要传递的数据 ,在事件处理函数中通过targert或currentTarget对象的datasett属性获取数据

2、模块

微信小程序提供了模块化开发的语法,,使用module.exports语法对外暴露接口,然后在需要使用模块的地方通过require()函数引入 模块。

四、处理逻辑

1、数学处理模块

模块代码如下:

javascript 复制代码
​
// 精确计算
module.exports = {
    target: 'num1',  //表示当前正在输入哪个数字,取num1或num2
    num1: '0',
    num2: '0',
     op: '',
  // 重置
  reset() {
    this.num1 = '0'
    this.num2 = '0'
    this.target = 'num1'
    this.op = ''
  },
  changeNum2: function()
  {
     this.target='num2'
  },
  setNum: function(arg1){
     this[this.target]=arg1
  },
  getNum: function(){
      return this[this.target]
  },
  add: function(arg1, arg2) {
    var r1, r2, m
    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))
    return (arg1 * m + arg2 * m) / m
  },
  sub: function(arg1, arg2) {
    var 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).toFixed(n)
  },
  mul: function(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)
  },
  div: function(arg1, arg2) {
    var 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)
  },
  // 进行运算
  getResult() {
    let result = 0
    if (this.op === '+') {
      result = this.add(this.num1, this.num2)
    } else if (this.op === '-') {
      result = this.sub(this.num1, this.num2)
    } else if (this.op === '×') {
      result = this.mul(this.num1, this.num2)
    } else if (this.op === '÷') {
      result =this. div(this.num1, this.num2)
    }
    return result
  }
}

​

模块全局变量:

target: 'num1', //表示当前正在输入哪个数字,取num1或num2

num1: '0', //第一个操作数

num2: '0', //第二个操作数

op: '', //操作符

模块函数:

changeNum2(): //设置当前操作数为第二操作数

setNum(): //设置操作数的值

getNum(): //获取操作数的值

getResult(): //获取计算结果

其它的 add,sub,mul,div分别为加、减、乘、除函数。

2、计算器处理逻辑

javascript 复制代码
// index.js
const calc = require('../../utils/calc.js')
Page({
   /**  页面的初始数据  */
  data: {
      num: '0',
      op:''
  },
  //设置变量标识
  numChangeFlag : false,
  execflag: false,
  resultflag: false,
  //数字按钮的事件处理函数
  numBtn: function(e) {
        //点击数字按钮,获取对应的数字,将其值赋给num 
         var  num=e.target.dataset.val
         if(this.resultflag){
              this.resetBtn()
         }
         if(this.numChangeFlag){
             this.numChangeFlag=false
             this.execflag=true
             this.data.num='0'
             calc.changeNum2()
         }
         //设置输入的数字
         calc.setNum(this.data.num=='0'? num  : this.data.num +num)
         //页面中显示数字
         this.setData({ num: calc.getNum() })
      },
  //运算符按钮处理函数
  opBtn: function(e){
         calc.op=e.target.dataset.val
         this.numChangeFlag=true
         //判断是否已输入第2个数字
         if(this.execflag){
              this.execflag=false
              //已经输入第2个数字,再判断是否有结果状态
              if(this.resultflag){
                  this.resultflag=false
              } else {
                  calc.num1=calc.getResult()
              }
         }

         this.setData({
              sub: calc.num1+' '+calc.op+' ',
              num: calc.num1
         }) 
      },
   //"="按钮事件处理函数
   execBtn: function(){
  //解决没有输入第2个数字,不能按=号问题
  if(this.numChangeFlag){
      this.numChangeFlag=false
      this.execflag=true
      calc.num2=this.data.num
  }
  //如果已经输入第2个数字,执行计算操作
     if(this.execflag){
         this.resultflag=true
         var result=calc.getResult()
         this.setData({
           sub: calc.num1+' '+calc.op+' '+calc.num2+'=',
           num: result
         })
         calc.num1=result
     }
   } ,
 //重置按钮事件处理函数
 resetBtn:function(){
       calc.reset()
       this.execflag=false
       this.numChangeFlag=false
       this.resultflag=false
       this.setData({
              sub: '',
              num: '0'
       })
 },
 //小数点按钮事件
 dotBtn:function(){
     //如果是计算结果状态,则重置计算器
      if(this.resultflag){
          this.resetBtn()
      }
    //如果等待输入第2个数字且还没有输入第2个数字,设为'0'
    if(this.numChangeFlag) {
          this.numChangeFlag=false
          calc.setNum('0.')
    } else if(this.data.num.indexOf('.')<0){
       //如果当前数字没有".",需要加上"."
       calc.setNum(this.data.num+'.')
    }
    this.setData({
          num: calc.getNum(),          
    })
 },
 //删除按钮事件处理函数
 delBtn:function(){
    //如果当前是计算结果状态,则重置计算器
     if(this.resultflag) {
        return this.resetBtn()
      }
      //非计算结果状态
      var num=this.data.num.substr(0,this.data.num.length-1)
      calc.setNum(num==='' || num==='-' || num==='-0.' ? '0' : num)   
      this.setData({
        num: calc.getNum()
      })
 },
//正负切换按钮事件处理函数
negBtn:function(){
      //如果是0,不加正负号
      if(this.data.num==='0' || this.data.num==='0.'){
             return 
      }
    //如果当前是计算结果状态,则重置计算器
    if(this.resultflag){
          this.resetBtn()
    } else if(this.data.num.indexOf('-')<0){
        //当前没有负号,加负号
        calc.setNum('-'+this.data.num)
    } else {
      //当前有负号,去掉负号
      calc.setNum(this.data.num.substr(1))
    }
    this.setData({
      num: calc.getNum()
    })
},
})

模块首先使用require()函数引入计算模块,其次是全局变量、事件处理函数,具体事件处理函数如下:

numBtn:数字键处理函数,具体逻辑如下:首先判断是否是结果状态,如果是结果状态则复位,否则判断是第二操作数状态,是则设置为第二操作数。最后,使用计算模块的setNum设置操作数,并使用setData进行双向绑定的数据显示。

execBtn:"="事件处理函数,此函数的主要作用是调用计算模块的getResult函数,获取计算结果,并使用setData进行双向绑定的数据显示。

其它的事件处理函数如代码所示,分别完成复位、小数点、删除等处理函数,处理逻辑请参照代码。

本文主要论述了微信小程序计算器的设置,从思路、界面、计算模块、处理逻辑等方面进行了详细的论述,并给出了源代码。

相关推荐
郭wes代码6 小时前
Cmd命令大全(万字详细版)
python·算法·小程序
.生产的驴11 小时前
SpringBoot 对接第三方登录 手机号登录 手机号验证 微信小程序登录 结合Redis SaToken
java·spring boot·redis·后端·缓存·微信小程序·maven
汤姆yu16 小时前
基于微信小程序的乡村旅游系统
微信小程序·旅游·乡村旅游
计算机徐师兄16 小时前
基于TP5框架的家具购物小程序的设计与实现【附源码、文档】
小程序·php·家具购物小程序·家具购物微信小程序·家具购物
曲辒净17 小时前
微信小程序实现二维码海报保存分享功能
微信小程序·小程序
朽木成才18 小时前
小程序快速实现大模型聊天机器人
小程序·机器人
peachSoda718 小时前
随手记:小程序使用uni.createVideoContext视频无法触发播放
小程序
何极光18 小时前
uniapp小程序样式穿透
前端·小程序·uni-app
小墨&晓末19 小时前
【PythonGui实战】自动摇号小程序
python·算法·小程序·系统安全
oil欧哟1 天前
🤔认真投入一个月做的小程序,能做成什么样子?有人用吗?
前端·vue.js·微信小程序