小程序 - 计算器

news2024/12/27 23:22:55

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

目录

计算器

功能描述

准备工作

创建项目

配置导航栏

创建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()
        })
    }
})

功能截图

总结

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

在wsl2中安装archlinux

在之前的博客中&#xff0c;我介绍了如何在虚拟机或者真实机上安装archlinux并且进行一定的配置&#xff0c;但是实际上Linux不管怎么配置在日常使用中都没有Windows简单便利&#xff0c;在开发有关Linux的程序时过去用虚拟机或者直接在Windows上使用ssh在远程服务器上进行开发…

Python毕业设计选题:基于大数据的淘宝电子产品数据分析的设计与实现-django+spark+spider

开发语言&#xff1a;Python框架&#xff1a;djangoPython版本&#xff1a;python3.7.7数据库&#xff1a;mysql 5.7数据库工具&#xff1a;Navicat11开发软件&#xff1a;PyCharm 系统展示 管理员登录 管理员功能界面 电子产品管理 系统管理 数据可视化分析看板展示 摘要 本…

点动和自锁混合控制

中继&#xff1a;KA 线圈有电&#xff0c;常开吸合&#xff0c;常闭断开 SB1——>电机转&#xff08;自锁&#xff09;——>KA1&#xff08;自锁标志位&#xff09; SB2——>电机停 SB3——>电机点动——>KA2&#xff08;点动标志位&#xff09; 严禁出现双…

Linux权限机制深度解读:系统安全的第一道防线

文章目录 前言‼️一、Linux权限的概念‼️二、Linux权限管理❕2.1 文件访问者的分类&#xff08;人&#xff09;❕2.2 文件类型和访问权限&#xff08;事物属性&#xff09;✔️1. 文件类型✔️2. 基本权限✔️3. 权限值的表示方法 ❕2.3 文件访问权限的相关设置方法✔️1. ch…

代码随想录算法训练营第51期第8天 | 344. 反转字符串、541.反转字符串 II、卡码网:54.替换数字

344. 反转字符串 344. 反转字符串https://leetcode.cn/problems/reverse-string/1.这道题很简单&#xff0c;直接使用双指针就可以 2.这里有一个可以优化的点&#xff0c;left和right-- 可以放在字符串替换的时候完成&#xff0c;没必要单独写 void reverseString(char* s, …

Linux CentOS

​阿里云开源镜像下载链接 https://mirrors.aliyun.com/centos/7/isos/x86_64/ VMware 安装 CentOS7 自定义 下一步 选择稍后安装操作系统 选择 输入 查看物理机CPU内核数量 CtrlShiftEsc 总数不超过物理机内核数量 推荐内存 自选 推荐 推荐 默认 拆分成多个 默认 自定义硬件…

NineData云原生智能数据管理平台新功能发布|2024年11月版

本月发布 8 项更新&#xff0c;其中重点发布 2 项、功能优化 6 项。 重点发布 数据库 Devops - 数据生成支持多个数据源 NineData 支持在数据库中自动生成符合特定业务场景的随机数据&#xff0c;用于模拟实际生产环境中的数据情况&#xff0c;帮助用户在不使用真实数据的情况…

Altium Designer基础知识2:交互式差分布线

Altium Designer基础知识2&#xff1a;交互式差分布线 一、本文内容与前置知识点1. 本文内容2. 所用软件 二、差分式布线介绍1. 介绍2. 使用场景 三、布线流程1. 创建差分式布线对2. 布线 一、本文内容与前置知识点 1. 本文内容 Altium Designer的基础知识&#xff0c;差分布…

【从零开始的LeetCode-算法】74. 搜索二维矩阵

给你一个满足下述两条属性的 m x n 整数矩阵&#xff1a; 每行中的整数从左到右按非严格递增顺序排列。每行的第一个整数大于前一行的最后一个整数。 给你一个整数 target &#xff0c;如果 target 在矩阵中&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。…

人工智能助力SEO优化关键词策略提升网站流量

内容概要 在当今数字化迅速发展的时代&#xff0c;人工智能&#xff08;AI&#xff09;已成为SEO优化中不可或缺的工具。通过使用先进的智能算法&#xff0c;AI可以分析用户行为数据&#xff0c;从而洞察用户的搜索意图和偏好。这样的分析不仅能帮助网站管理者了解目标受众&am…

GPT vs Claude到底如何选?

美国当地时间6月20日&#xff0c;OpenAI的“劲敌”Anthropic公司发布了最新模型Claude 3.5 Sonnet。据Anthropic介绍&#xff0c;该模型是Claude 3.5系列模型中的首个版本&#xff0c;也是Anthropic迄今为止发布的“最强大、最智能”的模型。它不仅在性能上超越了竞争对手和自家…

设计模式——Chain(责任链)设计模式

摘要 责任链设计模式是一种行为设计模式&#xff0c;通过链式调用将请求逐一传递给一系列处理器&#xff0c;直到某个处理器处理了请求或所有处理器都未能处理。它解耦了请求的发送者和接收者&#xff0c;允许动态地将请求处理职责分配给多个对象&#xff0c;支持请求的灵活传…

SQLite:DDL(数据定义语言)的基本用法

SQLite&#xff1a;DDL&#xff08;数据定义语言&#xff09;的基本用法 1 主要内容说明2 相关内容说明2.1 创建表格&#xff08;create table&#xff09;2.1.1 SQLite常见的数据类型2.1.1.1 integer&#xff08;整型&#xff09;2.1.1.2 text&#xff08;文本型&#xff09;2…

【Elasticsearch】实现分布式系统日志高效追踪

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/literature?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;…

WEB安全 PHP学习

PHP基础 PHP编码显示问题 header ("Content-type: text/html; charsetgb2312"); header("Content-Type: text/html;charsetutf-8"); windows需要使用gbk编码显示 源码是 <?php header ("Content-type: text/html; charsetgb2312"); sys…

MySQL 单表练习

DQL练习1-学生表 创建如下学生表 create table student( id int, name varchar(20), gender varchar(20), chinese int, math int, english int ); insert into student values (1,张明,男,89,78,90), (2,李进,男…

详解Java数据库编程之JDBC

目录 首先创建一个Java项目 在Maven中央仓库下载mysql connector的jar包 针对MySQL版本5 针对MySQL版本8 下载之后&#xff0c;在IDEA中创建的项目中建立一个lib目录&#xff0c;然后把刚刚下载好的jar包拷贝进去&#xff0c;然后右键刚刚添加的jar包&#xff0c;点击‘添…

第32天:安全开发-JavaEE应用Servlet路由技术JDBCMybatis数据库生命周期

时间轴&#xff1a; 32天主要学习内容&#xff1a; 1、JavaEE-HTTP-Servlet技术 2、JavaEE-数据库-JDBC&Mybatis java技术使用历史&#xff08;2023 &#xff09;&#xff1a; JavaEE-HTTP-Servlet&路由&周期: java学习范围&#xff1a; 3、Java: 功能:数据…

【大数据技术基础】 课程 第3章 Hadoop的安装和使用 大数据基础编程、实验和案例教程(第2版)

第3章 Hadoop的安装和使用 3.1 Hadoop简介 Hadoop是Apache软件基金会旗下的一个开源分布式计算平台&#xff0c;为用户提供了系统底层细节透明的分布式基础架构。Hadoop是基于Java语言开发的&#xff0c;具有很好的跨平台特性&#xff0c;并且可以部署在廉价的计算机集群中。H…

VTK中矩阵vtkMatrix4x4类的介绍和使用

1、矩阵-齐次坐标介绍 常见的点一般是Pt&#xff08;X,Y,Z&#xff09;&#xff0c;相当于一个13矩阵&#xff0c;而矩阵相乘的话一般是第一个矩阵的列数要等于第二个矩阵的行数。此处需要引入齐次坐标的概念&#xff1a;从广义上讲&#xff0c;齐次坐标就是用n1维向量表示n 维…