小程序 - 计算器

小程序交互练习 - 计算器小程序

目录

计算器

功能描述

准备工作

创建项目

配置导航栏

创建utils目录

math.js文件内容

calc.js文件内容

页面内容

页面样式内容

页面脚本事件

功能截图

总结


计算器

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

功能描述

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

准备工作

创建项目

在微信开发者工具中创建一个微信小程序项目,项目名称为“计算器”​,模板选择“不使用模板”。

配置导航栏

在pages/index/index.json文件中配置页面导航栏,具体代码如下:

{
  "usingComponents": {
    "navigation-bar": "/components/navigation-bar/navigation-bar"
  },
  "navigationBarTitleText": "计算器"
}

创建utils目录

在项目根目录中创建utils目录,加载math.js和cals.js文件。

math.js文件内容
// 精准计算功能,用于解决JavaScript浮点数运算精度不准确的问题
module.exports = {
    // 加法
    add: function (a, b) {
      var r1, r2, m
      try {
        r1 = a.toString().split('.')[1].length
      } catch (e) {
        r1 = 0
      }
      try {
        r2 = b.toString().split('.')[1].length
      } catch (e) {
        r2 = 0
      }
      m = Math.pow(10, Math.max(r1, r2))
      return (a * m + b * m) / m
    },
    // 减法
    sub: function (a, b) {
      var r1, r2, m, n
      try {
        r1 = a.toString().split('.')[1].length
      } catch (e) {
        r1 = 0
      }
      try {
        r2 = b.toString().split('.')[1].length
      } catch (e) {
        r2 = 0
      }
      m = Math.pow(10, Math.max(r1, r2))
      // 动态控制精度长度
      n = (r1 >= r2) ? r1 : r2
      return ((a * m - b * m) / m).toFixed(n)
    },
    // 乘法
    mul: function (a, b) {
      var m = 0,
        s1 = a.toString(),
        s2 = b.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 (a, b) {
      var t1 = 0,
        t2 = 0,
        r1, r2
      try {
        t1 = a.toString().split('.')[1].length
      } catch (e) {}
      try {
        t2 = b.toString().split('.')[1].length
      } catch (e) {}
  
      r1 = Number(a.toString().replace('.', ''))
      r2 = Number(b.toString().replace('.', ''))
      return (r1 / r2) * Math.pow(10, t2 - t1)
    }
  }  
calc.js文件内容
// 引入math.js模块,获取math对象
const math = require('./math.js')
// 计算器中的数字处理
module.exports = {
  target: 'num1', // 表示当前正在输入哪个数字,取num1或num2
  num1: '0', // 保存第1个数字
  num2: '0', // 保存第2个数字
  op: '', // 运算符,值可以是+、-、×、÷

  // 设置当前数字
  setNum(num) {
    this[this.target] = num
  },
  // 获取当前数字
  getNum() {
    return this[this.target]
  },
  // 切换到第2个数字
  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.wxml文件中编写“计算器”微信小程序的页面结构,

具体内容如下:

<!--index.wxml-->
<navigation-bar title="计算器" back="{{false}}" color="black" background="#FFF"></navigation-bar>
<!-- 结果区域 -->
<view class="result">
    <!-- 当前计算式 -->
    <view class="result-sub">{{sub}}</view>
    <!-- 当前计算结果 -->
    <view class="result-num">{{num}}</view>
</view>
<!-- 按钮区域 -->
<view class="btns">
    <!-- 第一行按钮 -->
    <view>
        <!-- 清除按钮 -->
        <view hover-class="bg" hover-start-time="50" bind:tap="resetBtn">C</view>
        <!-- 删除按钮 -->
        <view hover-class="bg" hover-start-time="50" bind:tap="delBtn">DEL</view>
        <!-- 正负号切换按钮 -->
        <view hover-class="bg" hover-start-time="50" bind:tap="negBtn">+/-</view>
        <!-- 除号按钮 (+:Positive,-:Negtive)-->
        <view hover-class="bg" hover-start-time="50" bind:tap="opBtn" data-val="÷">÷</view>
    </view>
    <!-- 第二行按钮 -->
    <view>
        <!-- 7按钮 -->
        <view hover-class="bg" hover-start-time="50" bind:tap="numBtn" data-val="7">7</view>
        <!-- 8按钮 -->
        <view hover-class="bg" hover-start-time="50" bind:tap="numBtn" data-val="8">8</view>
        <!-- 9按钮 -->
        <view hover-class="bg" hover-start-time="50" bind:tap="numBtn" data-val="9">9</view>
        <!-- 乘号按钮-->
        <view hover-class="bg" hover-start-time="50" bind:tap="opBtn" data-val="×">×</view>
    </view>
    <!-- 第三行按钮 -->
    <view>
        <!-- 4按钮 -->
        <view hover-class="bg" hover-start-time="50" bind:tap="numBtn" data-val="4">4</view>
        <!-- 5按钮 -->
        <view hover-class="bg" hover-start-time="50" bind:tap="numBtn" data-val="5">5</view>
        <!-- 6按钮 -->
        <view hover-class="bg" hover-start-time="50" bind:tap="numBtn" data-val="6">6</view>
        <!-- 减号按钮-->
        <view hover-class="bg" hover-start-time="50" bind:tap="opBtn" data-val="-">-</view>
    </view>
    <!-- 第四行按钮 -->
    <view>
        <!-- 4按钮 -->
        <view hover-class="bg" hover-start-time="50" bind:tap="numBtn" data-val="1">1</view>
        <!-- 5按钮 -->
        <view hover-class="bg" hover-start-time="50" bind:tap="numBtn" data-val="2">2</view>
        <!-- 6按钮 -->
        <view hover-class="bg" hover-start-time="50" bind:tap="numBtn" data-val="3">3</view>
        <!-- 减号按钮-->
        <view hover-class="bg" hover-start-time="50" bind:tap="opBtn" data-val="+">+</view>
    </view>
    <!-- 第五行按钮 -->
    <view>
        <!-- 0按钮 -->
        <view hover-class="bg" hover-start-time="50" bind:tap="numBtn" data-val="0">0</view>
        <!-- 点按钮 -->
        <view hover-class="bg" hover-start-time="50" bind:tap="dotBtn">.</view>
        <!-- 等号按钮 —— 进行计算 -->
        <view hover-class="bg" hover-start-time="50" bind:tap="execBtn">=</view>
    </view>
</view>

页面样式内容

在pages/index/index.wxss文件中编写页面样式,具体代码如下:

/**index.wxss**/
/* 页面样式 */
page {
    height: 100vh;
    display: flex;
    flex-direction: column;
    color: #555;
  }
  
  /* 结果区域样式 */
  .result {
    flex: 1;  /* 垂直均分手机屏幕,因为flex-direction:column */
    background-color: #f3f6fe;
    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 {
    flex: 1;
    display: flex;
    flex-direction: column;
    font-size: 48rpx;
    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; /* 主轴居住 - 水平居中 */
  }
  
  /* 0按钮跨2列,view:first-child ~ view:nth-child(1) */
  .btns > view:last-child > view:nth-child(1) {
    flex-basis: 50%;
  }
  
  /* 清除样式类 */
  .btns > view:first-child > view:first-child {
    color: #f00;
  }
  
  /* 最后一列按钮样式 */
  .btns > view > view:last-child {
    color: #fc8100;
  }
      
  /* 按钮的盘旋样式类 */
  .bg {
    background: #eee;
  }
  

页面脚本事件

在pages/index/index.js文件的Page({})中编写页面逻辑,具体代码如下:

// index.js
const calc = require('../../utils/calc.js')
Page({
    data: {
        sub: '',
        num: '0'
    },
    // 设置3个变量标识
    numChangeFlag: false,
    execFlag: false,
    resultFlag: false,
    numBtn: function (e) {
        // 点击数字按钮,获取对应的数字,将其值赋给num
        var num = e.target.dataset.val
        if (this.resultFlag) {
            this.resetBtn()
        }
        // 设置输入的数字
        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
        // 判断是否已经输入第2个数字
        if (this.execFlag) {
            this.execFlag = false
            // 已经输入第2个数字,再判断当前是否为计算结果状态
            if (this.resultFlag) {
                // 当前是计算结果状态,需要在计算结果的基础上计算
                this.resultFlag = false
            } else {
                // 连续计算,将计算结果作为第1个数字
                calc.num1 = calc.getResult()
            }
        }
        this.numChangeFlag = true
        if (this.numChangeFlag) {
            this.numChangeFlag = false
            this.execFlag = true // 代表已输入第2个数字
            this.data.num = '0' // 将num设为0,避免数字进行拼接
            calc.changeNum2() // 将target切换到第2个数字
        }
        this.setData({
            sub: calc.num1 + ' ' + calc.op + ' ',
            num: calc.num2
        })
    },
    execBtn: function () {
        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
            calc.num2 = '0'
        }
    },
    resetBtn: function () {
        calc.reset() // 调用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()
        })
    },
    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()
        })
    },
    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()
        })
    }
})

功能截图

总结

小程序交互-计算器小程序

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/929946.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Ubuntu22.04安装Steam++(Watt toolkit)

Watt toolkit这个软件可以Github加速&#xff0c;非常方便。但是在Linux系统不好安装和正常使用。下面就以Ubuntu22.04来安装Watt toolkit软件。 在https://steampp.net/官网下载Linux版本&#xff1a; 然后解压这个压缩包&#xff1a; 然后在解压后的文件运行.sh文件&…

[382]基于springboot的辽B代驾管理系统

毕 业 设 计&#xff08;论 文&#xff09; 题目&#xff1a;辽B代驾管理系统 摘 要 使用旧方法对辽B代驾管理系统的信息进行系统化管理已经不再让人们信赖了&#xff0c;把现在的网络信息技术运用在辽B代驾管理系统的管理上面可以解决许多信息管理上面的难题&#xff0c;比…

github仓库自动同步到gitee

Github Actions是Github推出的自动化CI/CD的功能&#xff0c;我们将使用Github Actions让Github仓库同步到Gitee 同步的原理是利用 SSH 公私钥配对的方式拉取 Github 仓库的代码并推送到 Gitee 仓库中&#xff0c;所以我们需要以下几个步骤 生成 SSH 公私钥添加公钥添加私钥配…

H5与支付宝小程序通信,调起扫一扫

1.public/index.html加入代码 <script>if (navigator.userAgent.indexOf(AliApp) > -1) {document.writeln(<script src"https://appx/web-view.min.js" > < / script>);}window.$my my </script>2.vue其他具体页面加入代码 metho…

MySQL 慢查询日志记录 SQL优化 性能优化 日志查询 Explain

介绍 慢查询日志记录了所有执行时间超过指定参数(long_query_time&#xff0c;单位:秒&#xff0c;默认10秒)的所有SQL语句的日志。MySQL的慢查询日志默认没有开启&#xff0c;需要在MySQL的配置文件(/etc/my.cnf)中配置针对这些慢查询的SQL语句进行优化。 #开启慢查询开关 s…

chromedriver.exe编译

使用例子参考官网 ChromeDriver 使用入门 | Chrome for Developers Chrome for Testing availability 注意&#xff1a;chromedriver版本要与chromium版本号对应。 如何编译chromedriver chrome\test\chromedriver\BUILD.gn 1、ninja -C out/debug chromedriver_server…

JVM-程序计数器与栈

目录 程序计数器1&#xff1a;作用&#xff1a;2&#xff1a;特点&#xff1a;1&#xff1a;线程私有2&#xff1a;内存不会溢出 栈1&#xff1a;介绍&#xff1a;2&#xff1a;问题辨析&#xff1a; 程序计数器 1&#xff1a;作用&#xff1a; 程序计数器的作用就是记录下一条…

2025美赛数学建模常用数据库网站大全

优秀模板写作红宝书数学模型获取——更多资料请点击下方名片进群获取。 一、可以查询美国各个领域经济指标的网站: olap.epsnet.com.cnhttps://www.ers.usda.gov/data-products/rice-yearbook/www.ers.usda.govU.S. Energy Information Administration (EIA) www.eia.govhttp…

IS-IS三

目录 点到点邻接关系建立 ISIS修改链路类型 isis ppp-negotiation 3-way only 仅才用三次握手建立邻居 不向下兼容两次握手 两次握手 自身发送的&#xff08;Hello报文&#xff09;IIH 不携带 p2p adj TLV 不处理点到点邻接状态TLV 三次握手 …

Android10 设备死机的问题分析和解决

最近客户反馈一个问题&#xff0c;设备偶现死机。最后解决&#xff0c;在此记录。 目录 一死机的现象 二死机的类型 三 死机问题分析 1 死机现象的梳理 2 死机日志 1&#xff09;日志分析一 2 日志分析二&#xff08;正确方案&#xff09; 一死机的现象 设备死机&#x…

flex布局容易忽略的角色作用

目录 清除浮动 作用于行内元素 flex-basis宽度 案例一&#xff1a; 案例二&#xff1a; 案例三&#xff1a; flex-grow设置权重 案例一&#xff1a; 案例二&#xff1a; 简写flex-grow:1 0 auto; flex作为一维布局,行和列的使用&#xff0c;忽略的小角色&#xff0c;大…

如何安全地远程控制电脑

在当今的工作环境中&#xff0c;远程控制技术变得越来越关键。无论是远程工作、技术支持&#xff0c;还是常规的维护任务&#xff0c;远程控制都为用户带来了极大的方便。本文将详细探讨远程控制电脑的基本概念、如何安全地进行远程控制电脑的操作&#xff0c;以及RayLink远程控…

Linux实现地址转换和抓包

1.Linux实现地址转换 1.1 SNAT和DNAT NAT:地址转换SNAT:源地址转换DNAT:目的地址转换 内网——》外网&#xff1a;内网色的ip不能直接和公网ip通信&#xff0c;必须要把内网的地址转换成和公网ip通信的地址 外网——》内网&#xff1a;外网也不能直接和内网通信&#xff0c…

与火山引擎合作深化,观测云携一站式监控解决方案登陆万有商城

近日&#xff0c;观测云正式宣布入驻火山引擎的万有商城。作为一款全栈式数据观测与分析平台&#xff0c;观测云的加入不仅丰富了火山引擎生态&#xff0c;也为广大企业用户带来了更便捷的数字化工具&#xff0c;助力企业快速实现业务监控与优化。 从全球覆盖到本地深耕&#x…

一、web基础和http协议

前言 https://www.baidu.com/&#xff1a;URL&#xff08;是一种万维网寻址网址&#xff09; https://&#xff1a;协议&#xff0c;加密的http&#xff0c;加密的超文本传输协议&#xff0c;在数据传输之前要通过整数进行身份验证&#xff0c;验证通过才可以进行数据传输。 …

Vue生成类似于打卡页面

数据表格 <el-table :data"tableData" border height"calc(100vh - 240px)" :cell-style"cellFun"><el-table-column label"姓名" show-overflow-tooltip prop"name" align"center"/><el-table-co…

高通---Camera调试流程及常见问题分析

文章目录 一、概述二、Camera配置的整体流程三、Camera的代码架构图四、Camera数据流的传递五、camera debug FAQ 一、概述 在调试camera过程中&#xff0c;经常会遇到各种状况&#xff0c;本篇文章对camera调试的流程进行梳理。对常见问题的提供一些解题思路。 二、Camera配…

03_Webpack模块打包工具

03_Webpack模块打包工具 目录 知识点自测 以下哪个选项是 ECMAScript 默认导出和导入的语法&#xff1f; A&#xff1a;export 和 require B&#xff1a;module.exports {} 和 import 变量名 C&#xff1a;export default 和 import 变量名 D&#xff1a;export 和 import {…

FastAPI解决跨域报错net::ERR_FAILED 200 (OK)

目录 一、跨域问题的本质 二、FastAPI中的CORS处理 1. 安装FastAPI和CORS中间件 2. 配置CORS中间件 3. 运行FastAPI应用 三、解决跨域报错的步骤 四、案例&#xff1a;解决Vue.js与FastAPI的跨域问题 1. Vue.js前端应用 2. FastAPI后端API 3. 配置CORS中间件 4. 运行…

盲盒抽卡机小程序,打造趣味与惊喜并存的卡牌体验

随着科技的不断发展&#xff0c;线上营销方式已经渗透到了各行各业中&#xff0c;卡牌市场也不例外。传统的拆卡方式存在一些局限问题&#xff0c;为了提高消费者的拆卡体验&#xff0c;线上抽卡机系统成为了新的发展方式&#xff0c;提供全新的市场活力。 盲盒抽卡机系统是卡…