微信小程序案例3-2:计算器

文章来源:CSDN 发布日期:2024-04-12 分类:小程序博客 阅读( )

文章目录

  • 一、运行效果
  • 二、知识储备
    • (一)data-*自定义属性
    • (二)模块
  • 三、实现步骤
    • (一)准备工作
      • 1、创建项目
      • 2、设置导航栏
    • (二)实现页面结构
      • 1、编写页面整体结构
      • 2、编写结果区域结构
      • 3、编写按钮区域第一行按钮的结构
      • 4、编写按钮区域第二行按钮的结构
      • 5、编写按钮区域第三行按钮的结构
      • 6、编写按钮区域第四行按钮的结构
      • 7、编写按钮区域第五行按钮的结构
    • (三)实现页面样式
      • 1、编写页面样式
      • 2、编写结果区域样式
      • 3、编写按钮区域样式
        • (1)按钮区域总体样式
        • (2)按钮区域中每一行的样式
        • (4)按钮区域每一行中每个按钮的样式
        • (5)让0按钮垮2列
        • (6)清除按钮样式
        • (7)最后一列按钮样式
        • (8)按钮的盘旋样式类
      • 4、页面样式源码
    • (四)创建工具模块
      • 1、数字模块 - math.js
      • 2、计算模块 - calc.js
    • (五)实现页面逻辑
      • 1、引入calc.js文件
      • 2、编写页面所需数据
      • 3、设置变量标识
      • 4、编写数字按钮的点击事件处理函数
      • 5、编写运算符按钮的点击事件处理函数
      • 6、修改数字按钮点击事件函数代码
      • 7、编写等号按钮的点击事件处理函数
      • 8、重置按钮(`c`按钮)的点击事件处理函数
      • 9、小数点按钮的点击事件处理函数
      • 10、删除按钮的点击事件处理函数
      • 11、正负号切换按钮的点击事件处理函数
      • 12、特殊情况处理
        • (1)解决不能进行连等计算的问题
        • (2)解决数字拼接的问题
        • (3)解决没有输入第2个数字按等号按钮无法计算的问题
        • (4)解决无法通过运算符按钮实现连续计算的问题
      • 13、查看页面逻辑源码

一、运行效果

在这里插入图片描述

  • 录屏演示多次计算
    请添加图片描述

二、知识储备

(一)data-*自定义属性

请添加图片描述

(二)模块

请添加图片描述

三、实现步骤

(一)准备工作

1、创建项目

  • 创建微信小程序项目 - 计算器
    在这里插入图片描述
  • 单击【确定】按钮
    在这里插入图片描述
  • 按照惯例,做一些初始化工作
    在这里插入图片描述

2、设置导航栏

  • app.json设置window配置项
    在这里插入图片描述

(二)实现页面结构

  • pages/index/index.wxml文件

1、编写页面整体结构

在这里插入图片描述

2、编写结果区域结构

  • 两行内容:第一行是当前的计算式,第二行是当前计算结果
    在这里插入图片描述

3、编写按钮区域第一行按钮的结构

  • 第一行包含四个按钮:清楚按钮、删除按钮、正负号切换按钮、除号按钮
    在这里插入图片描述
  • 第20行代码设置了data-val自定义属性,用于区分不同按钮

4、编写按钮区域第二行按钮的结构

  • 第二行包含四个按钮:7按钮、8按钮、9按钮、乘号按钮
    在这里插入图片描述
  • 四个按钮都设置了data-val自定义属性,用于区分不同按钮

5、编写按钮区域第三行按钮的结构

  • 第三行包含四个按钮:4按钮、5按钮、6按钮、减号按钮
    在这里插入图片描述
  • 四个按钮都设置了data-val自定义属性,用于区分不同按钮

6、编写按钮区域第四行按钮的结构

  • 第四行包含四个按钮:1按钮、2按钮、3按钮、加号按钮
    在这里插入图片描述
  • 四个按钮都设置了data-val自定义属性,用于区分不同按钮

7、编写按钮区域第五行按钮的结构

  • 第五行包含四个按钮:0按钮、点按钮、3按钮、加号按钮
    在这里插入图片描述
  • 第68行设置了data-val自定义属性,用于区分不同按钮
  • 查看预览效果
    在这里插入图片描述

(三)实现页面样式

  • pages/index/index/wxss文件

1、编写页面样式

  • 设置page样式
    在这里插入图片描述

2、编写结果区域样式

  • 结果区域有三个样式类:resultresult-subresult-sum
    在这里插入图片描述
  • 修改页面结构,暂时查看预览效果
    在这里插入图片描述
  • 查看预览效果之后,将页面结构改回去

3、编写按钮区域样式

(1)按钮区域总体样式
  • .btns样式类
    在这里插入图片描述
  • 查看预览效果
    在这里插入图片描述
(2)按钮区域中每一行的样式
  • .btns > view样式类
    在这里插入图片描述
  • 查看预览效果
    在这里插入图片描述
(4)按钮区域每一行中每个按钮的样式
  • .btns > view > view样式类
    在这里插入图片描述
  • 查看预览效果
    在这里插入图片描述
(5)让0按钮垮2列
  • .btns > view:first-child > view:first-child选择器
    在这里插入图片描述
  • 查看预览效果
    在这里插入图片描述
(6)清除按钮样式
  • .btns > view:first-child > view:first-child选择器
    在这里插入图片描述
  • 查看预览效果
    在这里插入图片描述
(7)最后一列按钮样式
  • .btns > view > view:last-child选择器
    在这里插入图片描述
  • 查看预览效果
    在这里插入图片描述
(8)按钮的盘旋样式类
  • .bg选择器
    在这里插入图片描述
  • 查看预览效果
    请添加图片描述

4、页面样式源码

/**index.wxss**/page {  height: 100vh;  display: flex;  flex-direction: column;  color: #555;}/* 结果区域样式 */.result {  flex: 1; /*平均分布手机屏幕,因为flex-direction: column*/  background: #f3f3f3;  position: relative;}/* 当前计算式样式 */.result-sub {  font-size: 52rpx;  position: absolute;  bottom: 16vh;  right: 3vw;}/* 当前计算结果样式 */.result-num {  font-size: 100rpx;  position: absolute;  bottom: 3vh;  right: 3vw;}/* 按钮区域样式 */ .btns {   display: flex;   flex: 1;    flex-direction: column;    font-size: 38rpx;    border-top: 1rpx solid #ccc;    border-left: 1rpx solid #ccc; }/* 按钮区域中每一行的样式 */.btns>view {  display: flex;  flex: 1;}/* 按钮区域每一行中每个按钮的样式 */.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; /* 主轴居中 - 水平居中 */}/* 0按钮跨2列, .btns view:last-child view:nth-child(1) */.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: orange;}/* 按钮的盘旋样式类 */.bg {  background: #eee;}

(四)创建工具模块

在这里插入图片描述

  • 在项目根目录创建utils目录
    在这里插入图片描述

1、数字模块 - math.js

  • utils目录里创建math.js文件
    在这里插入图片描述
// 精准计算功能,用于解决JavaScript浮点数运算精度不准确的问题module.exports = {    // 加法    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)    }  }
  • 演示处理方式

2、计算模块 - calc.js

  • utils目录里创建calc.js文件
    在这里插入图片描述
// 引入math.js模块,获取math对象const math = require('./math')// 计算器中的数字处理module.exports = {  target : 'num1', //表示当前正在输入的哪个数字,取num1或num2  num1 : '0', //保存第一个数字  num2 : '', //保存第二个数字  op : '', //运算符,值可以是+、-、×、÷  //设置当前数字  setNum(num) {    this[this.target] = num  },  // 获取当前数字  getNum() {    return this[this.target]  },  // 切换到第二个数字  changeNum2() {    this.target = 'num2'  },  //重置  reset() {    this.num1 = '0'    this.num2 = '0'    this.target = 'num1'    this.op = ''  },  // 进行计算  getResult() {    let result = 0    if (this.op === '+') {      result =  math.add(this.num1,this.num2)    } else if (this.op === '-') {      result =  math.sub(this.num1,this.num2)    } else if (this.op === '×'){      result =  math.mul(this.num1,this.num2)    } else if (this.op === '÷') {      result =  math.div(this.num1,this.num2)    }    return result  }}

(五)实现页面逻辑

  • pages/index/index.js文件

1、引入calc.js文件

  • 引入calc.js文件,获取计算器对象
    在这里插入图片描述

2、编写页面所需数据

  • data里包含了两个数据:subnum
    在这里插入图片描述

3、设置变量标识

  • 设置三个变量标识:numChangeFlagexecFlagresultFlag在这里插入图片描述

4、编写数字按钮的点击事件处理函数

  • 数字按钮的点击事件处理函数 - btnNum()
    在这里插入图片描述
  • 编译之后,查看预览效果
    请添加图片描述
  • 如果不采用条件运算符来处理,就可能出现0打头的数字或一串0
    在这里插入图片描述

5、编写运算符按钮的点击事件处理函数

  • 运算符按钮的点击事件处理函数 - btnOperate()
    在这里插入图片描述

6、修改数字按钮点击事件函数代码

  • 按了运算符按钮之后,应该输入第二个数字,但是它会接到第一个数字后面,而不是输入第二个数字,为了解决这个问题,我们要在数字按钮点击事件函数里进行判断
    在这里插入图片描述
  • 重新编译,查看编译效果
    请添加图片描述

7、编写等号按钮的点击事件处理函数

  • 等号按钮的点击事件处理函数 - btnCalculate
    在这里插入图片描述

  • 重新编译,查看编译效果
    在这里插入图片描述

  • 显示算式和计算结果
    请添加图片描述

8、重置按钮(c按钮)的点击事件处理函数

  • 重置按钮的点击事件处理函数 - btnReset()
    在这里插入图片描述
  • 重新编译,查看预览效果
    请添加图片描述
  • 实现了重置按钮功能之后,我们可以进行多次计算

9、小数点按钮的点击事件处理函数

  • 小数点的点击事件处理函数 - btnDot()
    在这里插入图片描述
  • 重新编译,预览效果
    请添加图片描述

10、删除按钮的点击事件处理函数

  • 删除按钮的点击事件处理函数- btnDel()
    在这里插入图片描述
  • 重新编译,查看预览效果请添加图片描述

11、正负号切换按钮的点击事件处理函数

  • 正负号切换按钮的点击事件处理函数 - btnPosNeg()
    在这里插入图片描述
  • 重新编译,查看预览效果
    请添加图片描述

12、特殊情况处理

(1)解决不能进行连等计算的问题
  • 在计算器理输入“3 + 2 =”,计算结果显示“5”,再次点击“=”,此时,计算结果不会有变化。
  • 为了实现连等计算,应该在用户再次点击“=”按钮时,执行“5+2”的计算,就是将运算结果作为第一个数字来进行计算,于是得到结果“7”。
  • 修改btnCalculate()函数 - 绑定“=”按钮
    在这里插入图片描述
  • 重新编译,查看预览效果请添加图片描述
(2)解决数字拼接的问题
  • 在计算器中输入“4+5 = ”之后,计算结果显示“9”,再次输入“2 3”时,计算结果显示“923”,如下图所示,显然是不合理的
    在这里插入图片描述
  • 很简单,如果是结果状态,当你在输入数字时,立马将计算器重置。
  • 修改btnNum()事件处理函数
    在这里插入图片描述
  • 重新编译,检验是否解决了运算结果拼接数字的问题请添加图片描述
  • 显示了计算结果时,如果再点击数字按钮,不会拼接在计算结果后面,而会显示下一次计算的第一个数字。
(3)解决没有输入第2个数字按等号按钮无法计算的问题
  • 在计算器里输入“8 + ”之后,没有输入第2个数字,就去点击等号按钮,没有任何动静,我们希望此时将第一个数字也作为第2个数字参与计算,这样,屏幕就会出现“8 + 8 = ”的计算式与“16”的计算结果。
  • 修改ctnCalculate()函数
    在这里插入图片描述
  • 重新编译,查看预览效果
    请添加图片描述
(4)解决无法通过运算符按钮实现连续计算的问题
  • 在计算器里输入“5 + 3”之后,不是点击等号按钮,而是点击其他运算符按钮(减号按钮),这种连续计算,原来的代码搞不定,它是把第二个数字变成了第一个数字来处理,显然不合理,应该把计算结果当成第一个数字来进行处理。
  • 修改btnOperate()事件处理函数
    在这里插入图片描述
  • 重新编译,查看预览效果
    请添加图片描述

13、查看页面逻辑源码

// index.js// 引入calc.js文件,获取计算器对象 (calculator)const calc = require('../../utils/calc')Page({  // 页面所需数据  data: {    sub: '', //当前计算式    num: '0' //当前计算结果  },  // 设置变量标识  numChangeFlag: false, //值为false,标识当前尚未发生数字切换,值为true,表示切换到第二个数字,切换后在将值设置为false  execFlag: false, //值为false,表示尚未输入第二个数字,值为true,表示已经输入第二个数字  resultFlag: false, //值为false,表示当前处于等待输入状态,值为true,表示当前处于计算结果状态  // 数字按钮点击事件处理函数  btnNum(e) {    // 获取数字按钮对应的数字,赋值给Num    var num = e.target.dataset.val //dataset.val对应按钮的自定义属性data-val    // 如果是结果状态,那么计算器重置    if (this.resultFlag) {      this.btnReset()    }    // 判断是否该输入第二个数字    if (this.numChangeFlag) {      // 将数字切换标识设置为假      this.numChangeFlag = false      // 将execFlag标识设置为真      this.execFlag = true      // 将data.num设置为'0',避免第二个数字拼接到第一个数字后面,而是直接替换      this.data.num = '0'      //切换到第二个数字      calc.changeNum2()    }    //设置输入的数字(条件运算符避免0打头的数字或者一串0的数字出现)    calc.setNum(this.data.num === '0'? num:this.data.num + num)     //在页面显示输入的数字    this.setData ({      num: calc.getNum()    })  },  //运算符按钮的点击事件处理函数  btnOperate(e) {    // 保存上前的运算符    if (calc.op != '') {      var opOld = calc.op    }    //获取运算符按钮对应的运算符,赋给运算器对象的op属性    calc.op = e.target.dataset.val //dataset.val对应按钮的自定义属性data-val    // 将数字切换标识设置为真    this.numChangeFlag = true    // 判断是否已经输入第二个数字    if (this.execFlag) {      // 将输入第二个数字标识变量设置为假      this.execFlag = false      //判断是否为结果状态      if (this.resultFlag) {        // 将结果状态标识变量设置为假        this.resultFlag = false        //TODO      } else { //用户没有点击等号按钮,而是连续点击了运算符按钮        // 此时做连续计算,将计算结果作为第一个数字来处理        // 保存本次运算符        var opNew = calc.op        // 恢复上次运算符来进行计算        calc.op = opOld        calc.num1 = calc.getResult()        // 恢复成本次运算符        calc.op = opNew      }    }    // 刷新页面结果区域的两个数据    this.setData ({      sub: calc.num1 + ' ' + calc.op + ' ' + calc.num2, //当前计算式 ,此时第二个数字为空,等待用户输入      num: calc.num1 //当前计算结果,为什么是第一个数字呢?因为尚未输入第二个数字并且点击等号按钮    })  },  // 等号按钮的点击事件处理函数  btnCalculate () {    // 判断数字是否切换到第二个数字,尚未输入第二个数字    if (this.numChangeFlag) {      // 将数字切换标识变量设置为假      this.numChangeFlag = false      // 准备输入第二个数字,将输入第二个数字的标志变量设置为真      this.execFlag = true      // 将用户输入的第一个数字(显示在结果区域第二行的数字 - 结果)作为第二个数字参与计算      calc.num2 = this.data.num    }    // 判断是否已经输入第二个数字    if(this.execFlag) {      // 设置结果标识为真      this.resultFlag = true      // 调用计算器对象的getResult()函数获取计算结果      var result = calc.getResult()       // 属性页面结果区域的两个数据      this.setData({        sub: calc.num1 + ' ' + calc.op + calc.num2 + ' = ', //当前计算式        num: result //当前计算结果      })    }    // 将运算结果作为第一个数字    calc.num1 = result  },  // 重置按钮的点击事件处理函数  btnReset() {    // 调用计算器模块的事件重置函数    calc.reset()    // 初始化三个变量标识    this.numChangeFlag = false    this.execFlag = false    this.resultFlag = false    this.setData({      sub:'',      num:'0',    })  },  // 小数点按钮的点击事件处理函数  btnDot() {    // 判断是否为结果状态,重置计算器    if (this.resultFlag) {      this.btnReset()    }    // 切换到第二个数字等待输入,设为“0”    if (this.numChangeFlag) {      // 将数字切换标识设置为假      this.numChangeFlag = false      // 将execFlag标识设置为真      this.execFlag = true      // 目标切换到第二个数字      calc.changeNum2()      // 将数字设置为“0.”      calc.setNum('0.')    } else if (this.data.num.indexOf('.') < 0) {      // 当前数字没有“.”,那么将拼接“.”      calc.setNum(this.data.num + '.')    }    // 更新数据,刷新页面    this.setData({      num:calc.getNum()    })  },  // 删除按钮的点击事件处理函数  btnDel() {    // 判断是否为结果状态,重置计算器    if (this.resultFlag) {      this.btnReset()    }    // 非计算状态,将删除当前数字中最右边的一个字符    var num = this.data.num.substring(0,this.data.num.length - 1)    // 判断是否已经删除完有效数字,删完之后,继续按删除按钮,数字将置为0    calc.setNum(num === '' || num === '-' || num === '-0.' ? '0' : num)     // 更新数据,刷新页面    this.setData({      num:calc.getNum()    })  },    // 正负号按钮的点击事件处理函数    btnPosNeg() {      // 针对“0”,不加正负号      if (this.data.num === '0' || this.data.num === '0.') {        return       }      // 如果是结果状态,重置计算器      if (this.resultFlag) {        this.btnReset();      } else if (this.data.num.indexOf('-') < 0) { //数字前没有负号        // 在数字前添加一个“-”号        calc.setNum('-' + this.data.num)      } else { //数字前有负号        // 去掉数字的第一位        calc.setNum(this.data.num.substring(1))      }      // 更新数据,刷新页面      this.setData ({        num:calc.getNum()      })    }})

最新文章:

二维码