草庐IT

微信小程序计算器(含源码)、含js精确运算代码

l煎饼果子 2024-01-03 原文

目录

一、引言与效果图

 二、源码

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">C</view>
      <view class="col" hover-class="hover-bg" bindtap="delBtn">DEL</view>
      <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">7</view>
      <view class="col" hover-class="hover-bg" bindtap="numBtn" data-val="8">8</view>
      <view class="col" hover-class="hover-bg" bindtap="numBtn" data-val="9">9</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="4">4</view>
      <view class="col" hover-class="hover-bg" bindtap="numBtn" data-val="5">5</view>
      <view class="col" hover-class="hover-bg" bindtap="numBtn" data-val="6">6</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="1">1</view>
      <view class="col" hover-class="hover-bg" bindtap="numBtn" data-val="2">2</view>
      <view class="col" hover-class="hover-bg" bindtap="numBtn" data-val="3">3</view>
      <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">0</view>
      <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,欢迎在评论区指出

如果你有更好的实现方式,希望大家不吝赐教

经过评论区提醒,已对除法结果小数点后长度进行限制,同时修改了部分样式表,使得数字超长时会自动换行

有关微信小程序计算器(含源码)、含js精确运算代码的更多相关文章

  1. ruby - 如何在 buildr 项目中使用 Ruby 代码? - 2

    如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby​​

  2. ruby-on-rails - Rails 源代码 : initialize hash in a weird way? - 2

    在rails源中:https://github.com/rails/rails/blob/master/activesupport/lib/active_support/lazy_load_hooks.rb可以看到以下内容@load_hooks=Hash.new{|h,k|h[k]=[]}在IRB中,它只是初始化一个空哈希。和做有什么区别@load_hooks=Hash.new 最佳答案 查看rubydocumentationforHashnew→new_hashclicktotogglesourcenew(obj)→new_has

  3. ruby-on-rails - 使用一系列等级计算字母等级 - 2

    这里是Ruby新手。完成一些练习后碰壁了。练习:计算一系列成绩的字母等级创建一个方法get_grade来接受测试分数数组。数组中的每个分数应介于0和100之间,其中100是最大分数。计算平均分并将字母等级作为字符串返回,即“A”、“B”、“C”、“D”、“E”或“F”。我一直返回错误:avg.rb:1:syntaxerror,unexpectedtLBRACK,expecting')'defget_grade([100,90,80])^avg.rb:1:syntaxerror,unexpected')',expecting$end这是我目前所拥有的。我想坚持使用下面的方法或.join,

  4. ruby-on-rails - 浏览 Ruby 源代码 - 2

    我的主要目标是能够完全理解我正在使用的库/gem。我尝试在Github上从头到尾阅读源代码,但这真的很难。我认为更有趣、更温和的踏脚石就是在使用时阅读每个库/gem方法的源代码。例如,我想知道RubyonRails中的redirect_to方法是如何工作的:如何查找redirect_to方法的源代码?我知道在pry中我可以执行类似show-methodmethod的操作,但我如何才能对Rails框架中的方法执行此操作?您对我如何更好地理解Gem及其API有什么建议吗?仅仅阅读源代码似乎真的很难,尤其是对于框架。谢谢! 最佳答案 Ru

  5. ruby - 模块嵌套代码风格偏好 - 2

    我的假设是moduleAmoduleBendend和moduleA::Bend是一样的。我能够从thisblog找到解决方案,thisSOthread和andthisSOthread.为什么以及什么时候应该更喜欢紧凑语法A::B而不是另一个,因为它显然有一个缺点?我有一种直觉,它可能与性能有关,因为在更多命名空间中查找常量需要更多计算。但是我无法通过对普通类进行基准测试来验证这一点。 最佳答案 这两种写作方法经常被混淆。首先要说的是,据我所知,没有可衡量的性能差异。(在下面的书面示例中不断查找)最明显的区别,可能也是最著名的,是你的

  6. ruby - 寻找通过阅读代码确定编程语言的ruby gem? - 2

    几个月前,我读了一篇关于ruby​​gem的博客文章,它可以通过阅读代码本身来确定编程语言。对于我的生活,我不记得博客或gem的名称。谷歌搜索“ruby编程语言猜测”及其变体也无济于事。有人碰巧知道相关gem的名称吗? 最佳答案 是这个吗:http://github.com/chrislo/sourceclassifier/tree/master 关于ruby-寻找通过阅读代码确定编程语言的rubygem?,我们在StackOverflow上找到一个类似的问题:

  7. ruby - Net::HTTP 获取源代码和状态 - 2

    我目前正在使用以下方法获取页面的源代码:Net::HTTP.get(URI.parse(page.url))我还想获取HTTP状态,而无需发出第二个请求。有没有办法用另一种方法做到这一点?我一直在查看文档,但似乎找不到我要找的东西。 最佳答案 在我看来,除非您需要一些真正的低级访问或控制,否则最好使用Ruby的内置Open::URI模块:require'open-uri'io=open('http://www.example.org/')#=>#body=io.read[0,50]#=>"["200","OK"]io.base_ur

  8. 程序员如何提高代码能力? - 2

    前言作为一名程序员,自己的本质工作就是做程序开发,那么程序开发的时候最直接的体现就是代码,检验一个程序员技术水平的一个核心环节就是开发时候的代码能力。众所周知,程序开发的水平提升是一个循序渐进的过程,每一位程序员都是从“菜鸟”变成“大神”的,所以程序员在程序开发过程中的代码能力也是根据平时开发中的业务实践来积累和提升的。提高代码能力核心要素程序员要想提高自身代码能力,尤其是新晋程序员的代码能力有很大的提升空间的时候,需要针对性的去提高自己的代码能力。提高代码能力其实有几个比较关键的点,只要把握住这些方面,就能很好的、快速的提高自己的一部分代码能力。1、多去阅读开源项目,如有机会可以亲自参与开源

  9. UE4 源码阅读:从引擎启动到Receive Begin Play - 2

    一、引擎主循环UE版本:4.27一、引擎主循环的位置:Launch.cpp:GuardedMain函数二、、GuardedMain函数执行逻辑:1、EnginePreInit:加载大多数模块int32ErrorLevel=EnginePreInit(CmdLine);PreInit模块加载顺序:模块加载过程:(1)注册模块中定义的UObject,同时为每个类构造一个类默认对象(CDO,记录类的默认状态,作为模板用于子类实例创建)(2)调用模块的StartUpModule方法2、FEngineLoop::Init()1、检查Engine的配置文件找出使用了哪一个GameEngine类(UGame

  10. 7个大一C语言必学的程序 / C语言经典代码大全 - 2

    嗨~大家好,这里是可莉!今天给大家带来的是7个C语言的经典基础代码~那一起往下看下去把【程序一】打印100到200之间的素数#includeintmain(){ inti; for(i=100;i 【程序二】输出乘法口诀表#includeintmain(){inti;for(i=1;i 【程序三】判断1000年---2000年之间的闰年#includeintmain(){intyear;for(year=1000;year 【程序四】给定两个整形变量的值,将两个值的内容进行交换。这里提供两种方法来进行交换,第一种为创建临时变量来进行交换,第二种是不创建临时变量而直接进行交换。1.创建临时变量来

随机推荐