小程序交互练习 - 计算器小程序
目录
计算器
功能描述
准备工作
创建项目
配置导航栏
创建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, mtry {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, ntry {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 : r2return ((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, r2try {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或num2num1: '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 = 0if (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) {// 点击数字按钮,获取对应的数字,将其值赋给numvar num = e.target.dataset.valif (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 = trueif (this.numChangeFlag) {this.numChangeFlag = falsethis.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 = 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 = resultcalc.num2 = '0'}},resetBtn: function () {calc.reset() // 调用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()})},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()})}
})
功能截图
总结
小程序交互-计算器小程序