计算器微信小程序

Github路径

计算器小程序icon-default.png?t=O83Ahttps://github.com/Wangguangha/Calculator.git

项目结构

新建一个页面compute用于开发计算器功能

主要功能

计算器主要功能模块分析

效果演示

程序实现

UI规则

基本的规则如下:

  1. 输入框和按钮框长度要一致
  2. 按钮要设置圆角和间隔
  3. 模仿苹果手机的按钮风格

/* pages/home/home.wxss */

page {
  width: 100%;
  height: 100%;
}

/* 输入框的简单样式 */
input {
  margin: 10px 0;
  padding: 40rpx;
  border: 1px solid #ccc;
  border-radius: 5px;
  text-align: right;
  height: 15%;
  margin-bottom: 20rpx; /* 确保 input 和 button-grid 之间有间距 */
}

.containerBack {
  width: 100%;
  height: auto;
  min-height: 100%;
  background-color: #fff;
  display: flex;
  flex-direction: column;
}

/* 固定宽度 */
.fixedWidth {
  flex: 0 0 auto;
}

/* 自适应宽度 */
.autoFullWidth {
  flex: 1 1 auto;
}

.high {
  background: white;
  height: 253rpx;
  color: #fff;
}

.low {
  background: #f4f4f4;
  display: flex;
  flex-direction: column;
  flex: 1; /* 让它占据剩余空间 */
  padding: 20rpx;
  font-size: 38px;
}

.button-grid {
  display: flex;
  flex-direction: column;
  width: 100%; /* 调整为100%以适应容器宽度 */
}

.button-row {
  display: flex;
  justify-content: space-between;
  margin-bottom: 10rpx;
}

.grid-button {
  width: 100rpx;
  height: 100rpx;
  background-color: gray;
  color: black;
  border: none;
  border-radius: 5rpx;
  font-size: 28rpx;
  text-align: center;
  line-height: 100rpx;
  margin-right: 10rpx !important;  /*强制属性*/
}

.button-row .grid-button:last-child {
  margin-right: 0 !important; /* 最后一个按钮不需要右侧间距 */
}

.button-row:last-child .grid-button:first-child {
  flex: 3; /* 第一个按钮占用两倍空间 */
}

.button-row:last-child .grid-button:not(:first-child) {
  flex: 1; /* 其余按钮占用相同的空间 */
}

控件样式

<!--pages/home/home.wxml-->
<view class="containerBack">
  <view class="fixedWidth">
    <view class="high">
    </view>
  </view>
  <view class="autoFullWidth">
    <view class="low">
      <input type="number" auto-focus focus="{{focus}}" value="{{inputValue}}" title="res_show" bindinput="handleInput"/>
      <view class="button-grid">
        <view class="button-row">
          <button class="grid-button" bindtap="handleACButtonTap" data-index="0">AC</button>
          <button class="grid-button" bindtap="handleButtonTap" data-index="1" data-value="-">+/-</button>
          <button class="grid-button" bindtap="handleComputeButtonTap" data-index="2" data-value="5">%</button>
          <button class="grid-button" bindtap="handleComputeButtonTap" data-index="3" data-value="4">÷</button>
        </view>
        <view class="button-row">
          <button class="grid-button" bindtap="handleButtonTap" data-index="4" data-value="7">7</button>
          <button class="grid-button" bindtap="handleButtonTap" data-index="5" data-value="8">8</button>
          <button class="grid-button" bindtap="handleButtonTap" data-index="6" data-value="9">9</button>
          <button class="grid-button" bindtap="handleComputeButtonTap" data-index="7" data-value="3">×</button>
        </view>
        <view class="button-row">
          <button class="grid-button" bindtap="handleButtonTap" data-index="8" data-value="4">4</button>
          <button class="grid-button" bindtap="handleButtonTap" data-index="9" data-value="5">5</button>
          <button class="grid-button" bindtap="handleButtonTap" data-index="10" data-value="6">6</button>
          <button class="grid-button" bindtap="handleComputeButtonTap" data-index="11" data-value="2">-</button>
        </view>
        <view class="button-row">
          <button class="grid-button" bindtap="handleButtonTap" data-index="12" data-value="1">1</button>
          <button class="grid-button" bindtap="handleButtonTap" data-index="13" data-value="2">2</button>
          <button class="grid-button" bindtap="handleButtonTap" data-index="14" data-value="3">3</button>
          <button class="grid-button" bindtap="handleComputeButtonTap" data-index="15" data-value="1">+</button>
        </view>
        <view class="button-row">
          <button class="grid-button" bindtap="handleButtonTap" data-index="16" data-value="0">0</button>
          <button class="grid-button" bindtap="handleButtonTap" data-index="17" data-value=".">.</button>
          <button class="grid-button" bindtap="handleEqualButtonTap" data-index="19">=</button>
        </view>
      </view>
    </view>
  </view>
</view>

计算规则

// pages/home/home.js
Page({
  /**
   * 页面的初始数据
   */
  data: {
    inputValue: '', // 保存输入框的值
    operatorCode: 0,
    clearFlag: 0,
    num1: 0.0,
    num2: 0.0
  },

  inputChange(event) {
    this.setData({
      inputValue: event.detail.value // 更新 data 中的 inputValue
    });
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad(options) {

  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady() {

  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow() {

  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide() {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload() {

  },
  /*
  * 事件传参处理函数
  */
  sayHi(e) {
    console.log(e);
    var msg=e.target.dataset.msg;
    wx.showToast({
      title: '你好'+msg,
    })
  },
  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh(e) {

  },
  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom() {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage() {

  },
  
  handleInput(e) {
    let value = this.validateNumber(e.detail.value)
    this.setData({
      inputValue: value
    })
  },
  validateNumber(val) {
    // 先移除非数字、小数点和负号的字符
    let sanitizedValue = val.replace(/[^0-9.-]/g, '');

    // 仅允许负号在开头,其他位置的负号将被移除
    // 移除非法字符,确保负号只能在开头
    if (sanitizedValue.charAt(0) === '-') {
      sanitizedValue = '-' + sanitizedValue.slice(1).replace(/-/g, ''); // 确保负号只能在第一个字符
    } else {
      sanitizedValue = sanitizedValue.replace(/-/g, ''); // 移除非首位的负号
    }
    // 确保只保留第一个小数点,移除多余的小数点
    sanitizedValue = sanitizedValue.replace(/(\..*)\./g, '$1'); 

    //确保小数点前有至少一个数字,如果没有,则移除小数点
    const decimalIndex = sanitizedValue.indexOf('.');
    if (decimalIndex !== -1 && decimalIndex === 0) {
        // 小数点出现在第一位(无数字在前),则移除小数点
        sanitizedValue = sanitizedValue.replace('.', '');
    } else if (decimalIndex !== -1 && sanitizedValue.charAt(decimalIndex - 1) === '-') {
        // 小数点紧跟在负号后面(负号后没有数字),也移除小数点
        sanitizedValue = sanitizedValue.replace('.', '');
    }
    return sanitizedValue;
  },

  handleButtonTap(e) {
    if(this.data.clearFlag === 1){
      this.setData({
        inputValue: '',
        clearFlag: 0
      });
    }

    let index = e.currentTarget.dataset.index;
    let value = e.currentTarget.dataset.value;
    
    // 更新输入框的值
    let newValue;
    if (value === '-') {
      if(this.data.inputValue.charAt(0) === '-'){
        newValue = this.data.inputValue.replace('-', '');
      }else{
        newValue = value + this.data.inputValue;
      }
    } else {
      newValue = this.data.inputValue + value;
    }

    this.setData({
      inputValue: newValue
    });

    // 如果有手动绑定 input 事件处理函数,手动调用它
    this.handleInput({ detail: { value: newValue } });
  },

  // 按钮响应:AC
  handleACButtonTap(e) {
    // 清空输入框内容
    this.setData({
      inputValue: '',
      num1 : 0.0,
      num2 : 0.0,
      operatorCode : 0,
      clearFlag: 0
    });
  },

  // 按钮响应: +、-、*、/ 清空输入框内容
  handleComputeButtonTap(e) {
    this.data.num1 = parseFloat(this.data.inputValue);
    // 清空输入框内容
    this.setData({
      clearFlag: 1
    });

    // 记录运算符类型
    let opValue = e.currentTarget.dataset.value;
    // 设置运算符并显示结果
    this.setOperator(opValue);
  },

  // 按钮响应: = 输出运算结果
  handleEqualButtonTap(e) {
    this.data.num2 = parseFloat(this.data.inputValue);  // 保存第二个数值
    let result = 0.0;
    let op = parseInt(this.data.operatorCode, 10);

    // 根据运算符执行计算
    switch (op) {
      case 1:  // 加法
        result = this.data.num1 + this.data.num2;
        break;
      case 2:  // 减法
        result = this.data.num1 - this.data.num2;
        break;
      case 3:  // 乘法
        result = this.data.num1 * this.data.num2;
        break;
      case 4:  // 除法
        if (this.data.num2 !== 0) {
          result = this.data.num1 / this.data.num2;
        } else {
          wx.showToast({
            title: '除数不能为0',
            icon: 'none'
          });
          return;
        }
        break;
      case 5:  // 取余
        result = this.data.num1 % this.data.num2;
        break;
      default:
        wx.showToast({
          title: '无效操作符',
          icon: 'none'
        });
        break;
    }

    // 显示计算结果,并清空操作符和第二个数值
    let formattedResult = parseFloat(result.toFixed(4)); // 保留四位小数,并去掉多余的小数位

    this.setData({
      inputValue: formattedResult.toString(), // 转换为字符串
      num1:0.0,
      num2:0.0,
      clearFlag: 0
    });    
  },

  setOperator(op) {
    // 更新运算符状态
    this.setData({
      operatorCode : op
    }, () => {
      //这里的回调函数在 setData 完成后执行
    });
  },

  // 获取当前运算符
  getOperator() {
    return this.data.operatorCode;
  }
})
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值