微信小程序计算器(含源码)、含js精确运算代码
后台-插件-广告管理-内容页头部广告(手机) |
目录
一、引言与效果图
二、源码
0.目录结构:
1.xxxx.wxml文件
2.样式文件
(1)xxxx.less文件
(2)xxxx.wxss文件 (不会使用 less 的可以用这个)
3.xxxx.json文件
4.accurate.js
5.xxxx.js文件
三、结语
一、引言与效果图
最近在做一个记账本小程序,其中需要用到计算器,但是在网上找的代码,用起来不是不符合我的想法,就是看着非常难受,于是还是自己写了一个
二、源码
0.目录结构:
名字 ( test ) 是我随便取的,你们可以取别的,但是accurate.js的名字请勿改动
1.xxxx.wxml文件
对应上方目录结构的 : test.wxml
- <view class="counter">
- <view class="result">
- <view class="showResult">
- <view class="result-num">{{counter.posture[0]}}view>
- <view class="result-num">{{counter.posture[1]}}view>
- <view class="result-num">{{counter.posture[2]}}view>
- view>
- view>
- <view class="btns">
- <view class="row">
- <view class="col clear" hover-class="hover-bg" bindtap="resetBtn">Cview>
- <view class="col" hover-class="hover-bg" bindtap="delBtn">DELview>
- <view class="col chu" hover-class="hover-bg" bindtap="opBtn" data-val="%">%view>
- <view class="col" hover-class="hover-bg" bindtap="opBtn" data-val="÷">÷view>
- view>
- <view class="row">
- <view class="col" hover-class="hover-bg" bindtap="numBtn" data-val="7">7view>
- <view class="col" hover-class="hover-bg" bindtap="numBtn" data-val="8">8view>
- <view class="col" hover-class="hover-bg" bindtap="numBtn" data-val="9">9view>
- <view class="col" hover-class="hover-bg" bindtap="opBtn" data-val="×">×view>
- view>
- <view class="row">
- <view class="col" hover-class="hover-bg" bindtap="numBtn" data-val="4">4view>
- <view class="col" hover-class="hover-bg" bindtap="numBtn" data-val="5">5view>
- <view class="col" hover-class="hover-bg" bindtap="numBtn" data-val="6">6view>
- <view class="col" hover-class="hover-bg" bindtap="opBtn" data-val="-">-view>
- view>
- <view class="row">
- <view class="col" hover-class="hover-bg" bindtap="numBtn" data-val="1">1view>
- <view class="col" hover-class="hover-bg" bindtap="numBtn" data-val="2">2view>
- <view class="col" hover-class="hover-bg" bindtap="numBtn" data-val="3">3view>
- <view class="col" hover-class="hover-bg" bindtap="opBtn" data-val="+">+view>
- view>
- <view class="row">
- <view class="col zero" hover-class="hover-bg" bindtap="numBtn" data-val="0">0view>
- <view class="col" hover-class="hover-bg" bindtap="numBtn" data-val=".">.view>
- <view class="col save" hover-class="hover-bg" bindtap="finish">=view>
- view>
- view>
- view>
2.样式文件
我是用less写的,所以这里先放less文件(不知道less怎么使用的,可以往下滑,看到wxss文件)
对应上方目录结构的 : test.wxss 和 test.less
(1)xxxx.less文件
- page {
- display: flex;
- flex-direction: column;
- height: 100%;
- background-image: linear-gradient(to top, #a8edea 0%, #fed6e3 100%);
- }
- .counter {
- height: 100%;
- display: flex;
- flex-direction: column;
- font-size: 60rpx;
- border-top: 1rpx solid #ccc;
- border-left: 1rpx solid #ccc;
- .result {
- flex: 1;
- position: relative;
- width: 100%;
- box-sizing: border-box;
- display: flex;
- align-items: flex-end;
- justify-content: flex-end;
- border-bottom: 5rpx solid #d5dde1;
- background: rgba(215, 250, 252, 0.253);
- .showResult {
- display: flex;
- align-items: flex-end;
- justify-content: flex-end;
- flex-wrap: wrap;
- font-size: 100rpx;
- width: 100%;
- box-sizing: border-box;
- padding: 20rpx;
- .result-num {
- overflow-x: auto;
- text-align: end;
- word-wrap: break-word;
- }
- }
- }
- .btns {
- flex: 1;
- .row {
- display: flex;
- .col {
- flex-basis: 25%;
- height: 150rpx;
- border-right: 1rpx solid #ccc;
- border-bottom: 1rpx solid #ccc;
- box-sizing: border-box;
- display: flex;
- align-items: center;
- justify-content: center;
- font-size: 50rpx;
- &.clear {
- color: #f00;
- }
- &.zero {
- flex-basis: 50%;
- }
- &:last-child,
- &.chu {
- color: #008bfc;
- }
- &.save {
- color: #f90808;
- font-size: 80rpx;
- font-weight: 900;
- }
- &.hover-bg {
- background: rgba(255, 255, 255, 0.2);
- }
- }
- }
- }
- }
(2)xxxx.wxss文件 (不会使用 less 的可以用这个)
- page {
- display: flex;
- flex-direction: column;
- height: 100%;
- background-image: linear-gradient(to top, #a8edea 0%, #fed6e3 100%);
- }
- .counter {
- height: 100%;
- display: flex;
- flex-direction: column;
- font-size: 60rpx;
- border-top: 1rpx solid #ccc;
- border-left: 1rpx solid #ccc;
- }
- .counter .result {
- flex: 1;
- position: relative;
- width: 100%;
- box-sizing: border-box;
- display: flex;
- align-items: flex-end;
- justify-content: flex-end;
- border-bottom: 5rpx solid #d5dde1;
- background: rgba(215, 250, 252, 0.253);
- }
- .counter .result .showResult {
- display: flex;
- align-items: flex-end;
- justify-content: flex-end;
- flex-wrap: wrap;
- font-size: 100rpx;
- width: 100%;
- box-sizing: border-box;
- padding: 20rpx;
- }
- .counter .result .showResult .result-num {
- overflow-x: auto;
- text-align: end;
- word-wrap: break-word;
- }
- .counter .btns {
- flex: 1;
- }
- .counter .btns .row {
- display: flex;
- }
- .counter .btns .row .col {
- transition: all 0.3s;
- flex-basis: 25%;
- height: 150rpx;
- border-right: 1rpx solid #ccc;
- border-bottom: 1rpx solid #ccc;
- box-sizing: border-box;
- display: flex;
- align-items: center;
- justify-content: center;
- font-size: 50rpx;
- }
- .counter .btns .row .col.clear {
- color: #f00;
- }
- .counter .btns .row .col.zero {
- flex-basis: 50%;
- }
- .counter .btns .row .col:last-child,
- .counter .btns .row .col.chu {
- color: #008bfc;
- }
- .counter .btns .row .col.save {
- color: #f90808;
- font-size: 80rpx;
- font-weight: 900;
- }
- .counter .btns .row .col.hover-bg {
- background: rgba(255, 255, 255, 0.2);
- }
3.xxxx.json文件
对应上方目录结构的 : test.json
- {
- "usingComponents": {},
- "navigationBarTitleText": "计算器",
- "navigationBarBackgroundColor": "#f4dfe9"
- }
4.accurate.js
对应上方目录结构的 : accurate.js ,请勿改名
这个文件是用于进行精确计算的:因为js自带的浮点数计算有bug!用这个函数进行加减乘除,可以防止浮点数运算出现问题
- module.exports = {
- //加法 add
- add(arg1, arg2) {
- let 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;
- },
- //减法 subtraction
- sub(arg1, arg2) {
- let 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);
- },
- //乘法 multiplication
- mul(arg1, arg2) {
- let 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);
- },
- //除法 division
- div(arg1, arg2) {
- let 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);
- }
- }
5.xxxx.js文件
对应上方目录结构的 test.js
我的做法是,使用一个长度为3的数组,存储式子的 “左” “中” “右” 的数字或操作符,然后再进行一些特殊情况的处理
- //引入精确计算的js
- const acc = require('./accurate.js');
- Page({
- data: {
- counter: {
- posture: ['', '', ''], //存放式子,比如 1 + 12
- ansType: false, //判断是否是手动点击的等于号
- },
- },
- //输入数字
- numBtn(e) {
- let num = e.currentTarget.dataset.val
- let posture = this.data.counter.posture
- if (posture[1] === '') { //如果运算符为空,就在式子数组第0个位置放入内容
- //判断特殊情况1: 小数点
- if (num == '.' && posture[0] == '') { //如果是点,且字符串为空,就默认加上 0
- posture[0] = '0'
- } else if (num == '.' && posture[0].indexOf('.') > -1) { //如果已经有点了还按
- console.log('已经有点,不能再按');
- return
- }
- //判断特殊情况2:如果是手动点了等号之后,再按数字,不应该在原位置加,而是清空再加 (通过其它方式比如 “1+2+“ 调用的finish函数不算,需要是手动点击的,判断方法:手动点击的等号有事件对象e)
- if (this.data.counter.ansType) {
- posture[0] = ''
- this.setData({
- 'counter.ansType': false //生效一次即可取消
- })
- }
- //判断特殊情况3:如果这里面只有0,那么就删掉这个0,再增加(想输入小数点除外)
- if (num !== '.' &&posture[0] == '0') {
- posture[0] = ''
- }
- this.setData({
- 'counter.posture[0]': posture[0] + num
- })
- } else { //如果运算符不为空,就在式子数组第2个位置放入内容
- //判断特殊情况: 小数点
- if (num == '.' && posture[2] == '') { //如果是点,且字符串为空,就默认加上 0
- posture[2] = '0'
- } else if (num == '.' && posture[2].indexOf('.') > -1) { //如果已经有点了还按
- console.log('已经有点,不能再按');
- return
- }
- //判断特殊情况2:如果这里面只有0,那么就删掉这个0,再增加 (想输入小数点除外)
- if (num !== '.' && posture[2] == '0') {
- posture[2] = ''
- }
- this.setData({
- 'counter.posture[2]': posture[2] + num
- })
- }
- console.log(this.data.counter.posture);
- },
- //输入运算符
- opBtn(e) {
- let op = e.currentTarget.dataset.val
- let posture = this.data.counter.posture
- if (posture[2] == '') { //如果式子最后一位为空的话,就把符号放进去运算符位置
- this.setData({
- 'counter.posture[1]': op
- })
- } else { //否则就先运算,再放进去
- this.finish()
- this.setData({
- 'counter.posture[1]': op
- })
- }
- console.log(this.data.counter.posture);
- },
- //运算
- finish(e) {
- let posture = this.data.counter.posture
- let left = parseFloat(posture[0] || 0) //左数字 如果是空字符串就设置为0
- let right = parseFloat(posture[2] || 0) //右数字 如果是空字符串就设置为0
- let ans = 0 //答案
- console.log(left, right);
- switch (posture[1]) { //根据不同运算符,进行不同的运算
- case '+':
- ans = acc.add(left, right)
- break;
- case '-':
- ans = acc.sub(left, right)
- break;
- case '×':
- ans = acc.mul(left, right)
- break;
- case '÷':
- if (right == 0) { //如果数字不合规
- wx.showToast({
- title: '不能除 0 哦',
- icon: 'none'
- })
- ans = left
- } else {
- let _ans = acc.div(left, right)
- let x = String(_ans).indexOf('.') + 1;
- let y = String(_ans).length - x;
- if (y > 10) {
- ans = _ans.toFixed(10);
- } else {
- ans = _ans
- }
- }
- break;
- case '%':
- if (right == 0) { //如果数字不合规
- wx.showToast({
- title: '不能余 0 哦',
- icon: 'none'
- })
- ans = left
- } else {
- ans = left % right
- }
- break;
- default:
- ans = left
- break;
- }
- console.log(ans);
- posture = ['' + ans, '', ''] //清空数组,把答案放在第一位
- let ansType = false
- if (e) { //如果有事件对象,说明是手动点击的”=“,应该加一个标识符,点了=再点数字的时候,应该把左边数字清空再处理数字
- console.log('手动点击的等于号,后面点击数字时,将清空左边数字');
- ansType = true
- }
- this.setData({
- 'counter.posture': posture,
- 'counter.ansType': ansType
- })
- },
- //清空
- resetBtn() {
- this.setData({
- 'counter.posture': ['', '', ''],
- })
- },
- //退位
- delBtn() {
- let posture = this.data.counter.posture
- //从右到左的顺序删除
- if (posture[2]) { //如果最后一位不为空,就先删它
- posture[2] = posture[2].substr(0, posture[2].length - 1)
- } else if (posture[1]) { //如果符号位不为空,就删它
- posture[1] = ''
- } else if (posture[0]) { //如果第一位不为空,就删它
- posture[0] = posture[0].substr(0, posture[0].length - 1)
- } else return //否则就不做事
- this.setData({
- 'counter.posture': posture
- })
- console.log(this.data.counter.posture);
- },
- })
三、结语
这次的小程序源码分享到此结束,如果遇到了源码中出现了什么bug,欢迎在评论区指出
如果你有更好的实现方式,希望大家不吝赐教
经过评论区提醒,已对除法结果小数点后长度进行限制,同时修改了部分样式表,使得数字超长时会自动换行
1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。
在线投稿:投稿 站长QQ:1888636
后台-插件-广告管理-内容页尾部广告(手机) |