当前位置: 首页 > news >正文

微信小程序之计算器

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

一、开发思路

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”独占两个单元格。代码如下所示:

<!--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代码如下所示:

​
/**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、数学处理模块

模块代码如下:

​
// 精确计算
module.exports = {target: 'num1',  //表示当前正在输入哪个数字,取num1或num2num1: '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, mtry {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, ntry {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 : r2return ((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, r2try {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 = 0if (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、计算器处理逻辑

// 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.valif(this.resultflag){this.resetBtn()}if(this.numChangeFlag){this.numChangeFlag=falsethis.execflag=truethis.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.valthis.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=falsethis.execflag=truecalc.num2=this.data.num}//如果已经输入第2个数字,执行计算操作if(this.execflag){this.resultflag=truevar result=calc.getResult()this.setData({sub: calc.num1+' '+calc.op+' '+calc.num2+'=',num: result})calc.num1=result}} ,//重置按钮事件处理函数resetBtn:function(){calc.reset()this.execflag=falsethis.numChangeFlag=falsethis.resultflag=falsethis.setData({sub: '',num: '0'})},//小数点按钮事件dotBtn:function(){//如果是计算结果状态,则重置计算器if(this.resultflag){this.resetBtn()}//如果等待输入第2个数字且还没有输入第2个数字,设为‘0’if(this.numChangeFlag) {this.numChangeFlag=falsecalc.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进行双向绑定的数据显示。

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

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

相关文章:

微信小程序之计算器

在日常生活中&#xff0c;计算器是人们广泛使用的工具&#xff0c;可以帮助我们快速且方便地计算金额、成本、利润等。下面将会讲解如何开发一个“计算器”微信小程序。 一、开发思路 1、界面和功能 “计算器”微信小程序的页面效果如图所示 在计算器中可以进行整数和小数的…...

【logstash】logstash使用多个子配置文件

这里有个误区在pipelines.yml中写conf.d/*&#xff0c;实测会有问题&#xff0c;不同的filter处理逻辑会复用。 现在有两个从kafka采集日志的配置文件&#xff1a;from_kafka1.conf&#xff0c;from_kafka2.conf 修改pipelines.yml配置文件 config/pipelines.yml- pipeline.i…...

暴风骑士S9电摩上市,定义青少年骑行安全新标准

暴风骑士&#xff0c;作为全球高端儿童电动车的开创品牌&#xff0c;以其卓越的技术实力和创新精神&#xff0c;不断推动行业发展。如今&#xff0c;暴风骑士再次突破自我&#xff0c;推出了全新力作——S9青少年电摩。这款全新上市的青少年专属电摩&#xff0c;以其领先的安全…...

spring security如何适配盐存在数据库中的密码

19.token认证过滤器代码实现_哔哩哔哩_bilibili19.token认证过滤器代码实现是SpringSecurity框架教程-Spring SecurityJWT实现项目级前端分离认证授权-挑战黑马&尚硅谷的第20集视频&#xff0c;该合集共计41集&#xff0c;视频收藏或关注UP主&#xff0c;及时了解更多相关视…...

Go语言编程 学习笔记整理 第2章 顺序编程 后半部分

1.流程控制 1.1 条件语句 if a < 5 { return 0 } else { return 1 } 注意&#xff1a;在有返回值的函数中&#xff0c;不允许将“最终的”return语句包含在if...else...结构中&#xff0c; 否则会编译失败&#xff01;&#xff01;&#xff01; func example(x int) i…...

美团后端二面

美团后端二面 ……………………………… 两道场景 一道 数字转中文读法&#xff08;1000-》一千&#xff09; 0八股0自我介绍 反问 “您觉得我能过吗&#xff1f;” “这个需要横行对比之后才能有结果” ……………………………… 什么时候到岗 场景题 1 假设我有一个…...

学懂C语言(十六):对C语言作用域规则 局部变量、全局变量的认识

一、C 作用域规则 任何一种编程中&#xff0c;作用域是程序中定义的变量所存在的区域&#xff0c;超过该区域变量就不能被访问。C 语言中有三个地方可以声明变量&#xff1a; 局部变量&#xff1a;在函数或块内部全局变量&#xff1a;在所有函数外部形式参数&#xff1a;在函数…...

关于TS(typescript)的理论知识

关于TS&#xff08;typescript&#xff09;的理论知识 TypeScript 是一种由微软开发的开源编程语言&#xff0c;它是 JavaScript 的一个超集&#xff0c;添加了可选的静态类型和基于类的面向对象编程。TypeScript 最终会被编译成纯 JavaScript 代码&#xff0c;以便在任何支持 …...

【OpenCV C++20 学习笔记】基本图像容器——Mat

【OpenCV C20 学习笔记】基本图像容器——Mat 概述Mat内部结构引用计数机制颜色数据格式 显式创建Mat对象使用cv::Mat::Mat构造函数矩阵的数据项 使用数组进行初始化的构造函数cv::Mat::create函数MATLAB风格的初始化小型矩阵通过复制创建Mat对象 Mat对象的输出其他普通数据项的…...

枚举单例是怎么保证线程安全和防止反射的

枚举单例在Java中具有天然的线程安全性和防止反射攻击的特性&#xff0c;这是由于Java对枚举类型的特殊处理方式。以下是详细解释&#xff1a; 1. 线程安全性 Java 枚举类的特性 类加载机制&#xff1a;枚举类型在Java中是特殊的类&#xff0c;由JVM保证其线程安全性。枚举类…...

传知代码-智慧医疗:纹理特征VS卷积特征(论文复现)

代码以及视频讲解 本文所涉及所有资源均在传知代码平台可获取 论文链接&#xff1a;https://www.sciencedirect.com/science/article/abs/pii/S1076633223003537?__cf_chl_rt_tkJ9Aipfxyk5d.leu48P20ePFNd4B2aunaSmzVpXCg.7g-1721292386-0.0.1.1-6249 论文概述 今天我们把视线…...

数据结构中的八大金刚--------八大排序算法

目录 引言 一&#xff1a;InsertSort(直接插入排序) 二&#xff1a;ShellSort(希尔排序) 三&#xff1a;BubbleSort(冒泡排序) 四&#xff1a; HeapSort(堆排序) 五&#xff1a;SelectSort(直接选择排序) 六&#xff1a;QuickSort(快速排序) 1.Hoare版本 2.前后指针版本 …...

ACC2.【C语言】经验积累 栈区简单剖析

int main() {int i0;int arr[10]{1,2,3,4,5,6,7,8,9,10};for (i0;i<12;i){arr[i]0;printf("A");}return 0; } 执行后无限打印A 在VS2022&#xff0c;X86,Debug环境下&#xff0c;用监视后&#xff0c;原因是arr[12]的地址与i的地址重合&#xff08;数组越界&…...

c# 索引器

索引器&#xff08;Indexer&#xff09;允许你像访问数组一样&#xff0c;通过索引访问对象的属性或数据。索引器的主要用途是在对象内部封装复杂的数据结构&#xff0c;使得数据访问更加直观。下面是关于 C# 索引器的详细解释及示例&#xff1a; 基本语法 索引器的语法类似于…...

低代码如何加速数字化转型

数字化转型&#xff0c;正日益决定企业成功的关键。这里的一个关键因素是它可以以更快的速度和质量来实施技术计划。在当今瞬息万变的商业环境中&#xff0c;战略性地采用低代码平台对于旨在加快上市时间、增强业务敏捷性和促进跨团队无缝协作的首席技术官来说至关重要。日益增…...

Pytest进阶之fixture的使用(超详细)

目录 Fixture定义 Fixture使用方式 作为参数使用 Fixture间相互调用(作为参数调用) 作为conftest.py文件传入 Fixture作用范围Scope function class module session Fixture中params和ids Fixture中autouse Fixture中Name 总结 pytest fixture 是一种用来管理测试…...

GitHub 详解教程

1. 引言 GitHub 是一个用于版本控制和协作的代码托管平台&#xff0c;基于 Git 构建。它提供了强大的功能&#xff0c;使开发者可以轻松管理代码、追踪问题、进行代码审查和协作开发。 2. Git 与 GitHub 的区别 Git 是一个分布式版本控制系统&#xff0c;用于跟踪文件的更改…...

边界网关IPSEC VPN实验

拓扑&#xff1a; 实验要求&#xff1a;通过IPSEC VPN能够使PC2通过网络访问PC3 将整个路线分为三段 IPSEC配置在FW1和FW2上&#xff0c;在FW1与FW2之间建立隧道&#xff0c;能够传递IKE&#xff08;UDP500&#xff09;和ESP数据包&#xff0c;然后在FW1与PC2之间能够流通数据…...

力扣高频SQL 50题(基础版)第六题

文章目录 1378. 使用唯一标识码替换员工ID题目说明思路分析实现过程结果截图总结 1378. 使用唯一标识码替换员工ID 题目说明 Employees 表&#xff1a; ---------------------- | Column Name | Type | ---------------------- | id | int | | name | varchar | ------…...

在一个事物方法中开启新事物,完成对数据库的修改

在Java中&#xff0c;使用Transactional注解来管理事务非常常见。但是&#xff0c;在一个已经标记为Transactional的方法内部调用另一个也标记了Transactional的方法时&#xff0c;如果不正确处理&#xff0c;可能会导致一些意料之外的行为。这是因为默认情况下&#xff0c;Spr…...

MPNet:旋转机械轻量化故障诊断模型详解python代码复现

目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...

循环冗余码校验CRC码 算法步骤+详细实例计算

通信过程&#xff1a;&#xff08;白话解释&#xff09; 我们将原始待发送的消息称为 M M M&#xff0c;依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)&#xff08;意思就是 G &#xff08; x ) G&#xff08;x) G&#xff08;x) 是已知的&#xff09;&#xff0…...

【C语言练习】080. 使用C语言实现简单的数据库操作

080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...

涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战

“&#x1f916;手搓TuyaAI语音指令 &#x1f60d;秒变表情包大师&#xff0c;让萌系Otto机器人&#x1f525;玩出智能新花样&#xff01;开整&#xff01;” &#x1f916; Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制&#xff08;TuyaAI…...

学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”

2025年#高考 将在近日拉开帷幕&#xff0c;#AI 监考一度冲上热搜。当AI深度融入高考&#xff0c;#时间同步 不再是辅助功能&#xff0c;而是决定AI监考系统成败的“生命线”。 AI亮相2025高考&#xff0c;40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕&#xff0c;江西、…...

基于PHP的连锁酒店管理系统

有需要请加文章底部Q哦 可远程调试 基于PHP的连锁酒店管理系统 一 介绍 连锁酒店管理系统基于原生PHP开发&#xff0c;数据库mysql&#xff0c;前端bootstrap。系统角色分为用户和管理员。 技术栈 phpmysqlbootstrapphpstudyvscode 二 功能 用户 1 注册/登录/注销 2 个人中…...

协议转换利器,profinet转ethercat网关的两大派系,各有千秋

随着工业以太网的发展&#xff0c;其高效、便捷、协议开放、易于冗余等诸多优点&#xff0c;被越来越多的工业现场所采用。西门子SIMATIC S7-1200/1500系列PLC集成有Profinet接口&#xff0c;具有实时性、开放性&#xff0c;使用TCP/IP和IT标准&#xff0c;符合基于工业以太网的…...

redis和redission的区别

Redis 和 Redisson 是两个密切相关但又本质不同的技术&#xff0c;它们扮演着完全不同的角色&#xff1a; Redis: 内存数据库/数据结构存储 本质&#xff1a; 它是一个开源的、高性能的、基于内存的 键值存储数据库。它也可以将数据持久化到磁盘。 核心功能&#xff1a; 提供丰…...

高防服务器价格高原因分析

高防服务器的价格较高&#xff0c;主要是由于其特殊的防御机制、硬件配置、运营维护等多方面的综合成本。以下从技术、资源和服务三个维度详细解析高防服务器昂贵的原因&#xff1a; 一、硬件与技术投入 大带宽需求 DDoS攻击通过占用大量带宽资源瘫痪目标服务器&#xff0c;因此…...

[USACO23FEB] Bakery S

题目描述 Bessie 开了一家面包店! 在她的面包店里&#xff0c;Bessie 有一个烤箱&#xff0c;可以在 t C t_C tC​ 的时间内生产一块饼干或在 t M t_M tM​ 单位时间内生产一块松糕。 ( 1 ≤ t C , t M ≤ 10 9 ) (1 \le t_C,t_M \le 10^9) (1≤tC​,tM​≤109)。由于空间…...