|
|
@@ -0,0 +1,449 @@
|
|
|
+<template>
|
|
|
+ <uni-popup ref="popup">
|
|
|
+ <div style="width: 700rpx;">
|
|
|
+ <view :class="['cui-calculator','flex-cncc',size]">
|
|
|
+ <view class="cui-calculator-title" @click="tapCopy">
|
|
|
+ <text>{{toThousands(curNumber)}}</text>
|
|
|
+ </view>
|
|
|
+ <view class="cui-content">
|
|
|
+ <uni-row v-for="(row,index) in buttons" :key="index" class="row">
|
|
|
+ <uni-col v-for="(item,subIndex) in row" :key="subIndex"
|
|
|
+ :span="item.span?item.span:(24/row.length)">
|
|
|
+ <div class="col">
|
|
|
+ <view class="cui-cell flex-cncc"
|
|
|
+ :class="[(waitInputNumberTwo&&item.name==symbol)?'active':'',item.width == 2?'big':'',item.border?'border':'',item.type]"
|
|
|
+ @click.stop="tapItem(item)" @touchstart="touchStart">
|
|
|
+ <!-- <uni-icons v-if="item.type=='backspace'" custom-prefix="iconfont"
|
|
|
+ type="icon-backspace" color="#FF8000" size="26px"></uni-icons> -->
|
|
|
+ <span v-if="item.type=='backspace'">←</span>
|
|
|
+ <span v-else>{{item.name}}</span>
|
|
|
+ </view>
|
|
|
+ </div>
|
|
|
+ </uni-col>
|
|
|
+ </uni-row>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ </uni-popup>
|
|
|
+
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+ import Decimal from "decimal.js";
|
|
|
+
|
|
|
+ const toThousands = (num = 0) => {
|
|
|
+ return num.toString().replace(/\d+/, function(n) {
|
|
|
+ return n.replace(/(\d)(?=(?:\d{3})+$)/g, '$1,');
|
|
|
+ });
|
|
|
+ };
|
|
|
+
|
|
|
+ function isValidNumber(str) {
|
|
|
+ return Math.abs(parseFloat(str)) > 0 || str == "0";
|
|
|
+ }
|
|
|
+
|
|
|
+ export default {
|
|
|
+ props: {
|
|
|
+ size: {
|
|
|
+ type: String,
|
|
|
+ default: "normal" // small,normal
|
|
|
+ }
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ toThousands,
|
|
|
+ curNumber: '0', //计算器显示区域值
|
|
|
+ buttons: [
|
|
|
+ [{ //计算器各按键
|
|
|
+ name: 'C',
|
|
|
+ type: 'clear',
|
|
|
+ border: true
|
|
|
+ }, {
|
|
|
+ name: 'backspace',
|
|
|
+ type: 'backspace',
|
|
|
+ border: true
|
|
|
+ }, {
|
|
|
+ name: '%',
|
|
|
+ type: 'percent',
|
|
|
+ border: false
|
|
|
+ }, {
|
|
|
+ name: '/',
|
|
|
+ type: 'operator',
|
|
|
+ border: false
|
|
|
+ }],
|
|
|
+ [{
|
|
|
+ name: '7',
|
|
|
+ type: 'number',
|
|
|
+ border: true
|
|
|
+ }, {
|
|
|
+ name: '8',
|
|
|
+ type: 'number',
|
|
|
+ border: false
|
|
|
+ }, {
|
|
|
+ name: '9',
|
|
|
+ type: 'number',
|
|
|
+ border: false
|
|
|
+ }, {
|
|
|
+ name: '*',
|
|
|
+ type: 'operator',
|
|
|
+ border: false
|
|
|
+ }],
|
|
|
+ [{
|
|
|
+ name: '4',
|
|
|
+ type: 'number',
|
|
|
+ border: true
|
|
|
+ }, {
|
|
|
+ name: '5',
|
|
|
+ type: 'number',
|
|
|
+ border: false
|
|
|
+ }, {
|
|
|
+ name: '6',
|
|
|
+ type: 'number',
|
|
|
+ border: false
|
|
|
+ }, {
|
|
|
+ name: '+',
|
|
|
+ type: 'operator',
|
|
|
+ border: false
|
|
|
+ }],
|
|
|
+ [{
|
|
|
+ name: '1',
|
|
|
+ type: 'number',
|
|
|
+ border: true
|
|
|
+ }, {
|
|
|
+ name: '2',
|
|
|
+ type: 'number',
|
|
|
+ border: false
|
|
|
+ }, {
|
|
|
+ name: '3',
|
|
|
+ type: 'number',
|
|
|
+ border: false
|
|
|
+ }, {
|
|
|
+ name: '-',
|
|
|
+ type: 'operator',
|
|
|
+ border: false
|
|
|
+ }],
|
|
|
+ [{
|
|
|
+ name: '0',
|
|
|
+ type: 'number',
|
|
|
+ border: true,
|
|
|
+ span: 12
|
|
|
+ }, {
|
|
|
+ name: '.',
|
|
|
+ type: 'point',
|
|
|
+ border: false,
|
|
|
+ span: 6
|
|
|
+ }, {
|
|
|
+ name: '=',
|
|
|
+ type: 'equal',
|
|
|
+ border: false,
|
|
|
+ span: 6
|
|
|
+ }]
|
|
|
+ ],
|
|
|
+ numberOne: '', //变量一
|
|
|
+ symbol: '', //运算符
|
|
|
+ complete: false, //判断是否完成一次计算
|
|
|
+ waitInputNumberTwo: false,
|
|
|
+ formula: []
|
|
|
+ }
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ open() {
|
|
|
+ this.$refs["popup"].open();
|
|
|
+ },
|
|
|
+ setCurNumber(value) {
|
|
|
+ this.curNumber = value;
|
|
|
+ },
|
|
|
+ getCurNumber() {
|
|
|
+ return this.curNumber;
|
|
|
+ },
|
|
|
+
|
|
|
+ touchStart() {
|
|
|
+ uni.vibrateShort();
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 1. 无输入
|
|
|
+ * 2. 计算已完成
|
|
|
+ * 3. 1
|
|
|
+ * 4. 1.2
|
|
|
+ * 6. 1+
|
|
|
+ * 7. 1+.
|
|
|
+ * 8. 1+2.3
|
|
|
+ */
|
|
|
+ //计算器方法二:
|
|
|
+ tapItem: function(item) {
|
|
|
+ // console.log("!!", item)
|
|
|
+ switch (item.type) {
|
|
|
+ case 'point': //小数点
|
|
|
+ if (this.complete || this.waitInputNumberTwo) {
|
|
|
+ this.curNumber = '0';
|
|
|
+ this.complete = false;
|
|
|
+ }
|
|
|
+ if (!this.curNumber.includes('.')) {
|
|
|
+ this.curNumber = this.curNumber + '.';
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case 'number': //数字
|
|
|
+ if (this.complete || this.waitInputNumberTwo) {
|
|
|
+ this.complete = false;
|
|
|
+ this.curNumber = item.name;
|
|
|
+ // this.formula = [];
|
|
|
+ } else if ((this.curNumber + "").includes('.')) {
|
|
|
+ this.curNumber += item.name;
|
|
|
+ } else {
|
|
|
+ this.curNumber = parseInt(this.curNumber + item.name) + "";
|
|
|
+
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case 'percent':
|
|
|
+ if (isValidNumber(this.curNumber)) {
|
|
|
+ this.curNumber = Decimal.div(parseFloat(this.curNumber), 100);
|
|
|
+ } else if (this.numberOne) {
|
|
|
+ //取上一个数
|
|
|
+ this.curNumber = Decimal.div(parseFloat(this.numberOne), 100);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case 'sign':
|
|
|
+ if (isValidNumber(this.curNumber)) {
|
|
|
+ this.curNumber = "" + (0 - parseFloat(this.curNumber));
|
|
|
+ } else if (this.numberOne) {
|
|
|
+ //取上一个数
|
|
|
+ this.curNumber = "" + (0 - parseFloat(this.numberOne));
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case 'backspace':
|
|
|
+ let temp = "" + this.curNumber;
|
|
|
+ if (/e\+\d$/.test(temp)) {
|
|
|
+ temp = temp.substring(0, temp.length - 3);
|
|
|
+ } else {
|
|
|
+ temp = temp.substring(0, temp.length - 1);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (temp == "" || temp == '-') {
|
|
|
+ this.curNumber = '0';
|
|
|
+ } else {
|
|
|
+ this.curNumber = temp;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case 'operator': //运算符
|
|
|
+ // 加减乘除
|
|
|
+ this.complete = false;
|
|
|
+ if (this.waitInputNumberTwo) {
|
|
|
+ this.symbol = item.name;
|
|
|
+ } else {
|
|
|
+ if (this.numberOne && this.symbol && isValidNumber(this.curNumber)) {
|
|
|
+ this.curNumber = this.calc(this.symbol, this.numberOne, this.curNumber);
|
|
|
+ this.numberOne = this.curNumber;
|
|
|
+ this.symbol = item.name;
|
|
|
+ this.waitInputNumberTwo = true;
|
|
|
+ } else if (!this.numberOne && !this.symbol && isValidNumber(this.curNumber)) {
|
|
|
+ this.numberOne = this.curNumber;
|
|
|
+ this.symbol = item.name;
|
|
|
+ this.waitInputNumberTwo = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ break;
|
|
|
+ case 'equal': //等号
|
|
|
+ if (!this.complete) {
|
|
|
+ // console.log("!!!!!!!!!!!!", this.symbol, this.numberOne, this.curNumber)
|
|
|
+ if (this.numberOne) {
|
|
|
+ this.curNumber = this.calc(this.symbol, this.numberOne, this.curNumber);
|
|
|
+ } else {
|
|
|
+ this.curNumber = parseFloat(this.curNumber);
|
|
|
+ }
|
|
|
+ this.complete = true;
|
|
|
+ this.numberOne = '';
|
|
|
+ this.symbol = '';
|
|
|
+ }
|
|
|
+ // this.addToFormula(item);
|
|
|
+ break;
|
|
|
+ case 'clear': //清除符
|
|
|
+ this.clear();
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (item.type != "operator") {
|
|
|
+ this.waitInputNumberTwo = false;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // addToFormula(item) {
|
|
|
+ // if ("1234567890.".includes(item.name)) {
|
|
|
+ // if (this.formula.length) {
|
|
|
+ // this.formula[this.formula.length - 1] += item.name;
|
|
|
+ // } else {
|
|
|
+ // this.formula.push(item.name);
|
|
|
+ // }
|
|
|
+ // } else {
|
|
|
+ // this.formula.push(item.name);
|
|
|
+ // }
|
|
|
+ // },
|
|
|
+ // formulaLastIsSymbol() {
|
|
|
+ // return "-+*/".includes(this.formula[this.formula.length - 1]);
|
|
|
+ // },
|
|
|
+ /**
|
|
|
+ * 清除
|
|
|
+ * */
|
|
|
+ clear: function() {
|
|
|
+ this.curNumber = '0';
|
|
|
+ this.numberOne = '';
|
|
|
+ this.symbol = '';
|
|
|
+ this.compile = false;
|
|
|
+ this.formula = [];
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 除法
|
|
|
+ * */
|
|
|
+ calc: function(symbol, arg1, arg2) {
|
|
|
+ if (symbol == '-') {
|
|
|
+ return Decimal.sub(arg1, arg2);
|
|
|
+ } else if (symbol == '+') {
|
|
|
+ return Decimal.add(arg1, arg2);
|
|
|
+ } else if (symbol == '*') {
|
|
|
+ return Decimal.mul(arg1, arg2);
|
|
|
+ } else if (symbol == '/') {
|
|
|
+ return Decimal.div(arg1, arg2);
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ tapCopy() {
|
|
|
+ uni.setClipboardData({
|
|
|
+ data: "" + this.curNumber,
|
|
|
+ success: () => {
|
|
|
+ uni.showToast({
|
|
|
+ title: "复制成功"
|
|
|
+ })
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="less">
|
|
|
+ .cui-calculator {
|
|
|
+ background-color: #333333;
|
|
|
+ box-shadow: 0 2px 4px rgba(0, 0, 0, .12), 0 0 6px rgba(0, 0, 0, .04);
|
|
|
+ width: 100%;
|
|
|
+ }
|
|
|
+
|
|
|
+ .cui-calculator-title,
|
|
|
+ .cui-calculator-formula {
|
|
|
+ width: 100%;
|
|
|
+ height: 120rpx;
|
|
|
+ line-height: 120rpx;
|
|
|
+ padding: 0 24rpx;
|
|
|
+ text-align: right;
|
|
|
+ background-color: #333333;
|
|
|
+ font-size: 50rpx;
|
|
|
+ font-weight: 600;
|
|
|
+ color: #FFFFFF;
|
|
|
+ box-sizing: border-box;
|
|
|
+ overflow: auto;
|
|
|
+ }
|
|
|
+
|
|
|
+ .cui-content {
|
|
|
+ width: 100%;
|
|
|
+ background-color: #FFFFFF;
|
|
|
+ // display: flex;
|
|
|
+ // flex-direction: row;
|
|
|
+ // justify-content: flex-start;
|
|
|
+ // align-items: flex-start;
|
|
|
+ // flex-wrap: wrap;
|
|
|
+ box-sizing: border-box;
|
|
|
+ border: 1px #f5f5f5 solid;
|
|
|
+
|
|
|
+
|
|
|
+ .row {
|
|
|
+ width: 100%;
|
|
|
+ background-color: #A5A4A4;
|
|
|
+ }
|
|
|
+
|
|
|
+ .col {
|
|
|
+ height: 98rpx;
|
|
|
+ line-height: 98rpx;
|
|
|
+ padding: 6rpx;
|
|
|
+ box-sizing: border-box;
|
|
|
+ }
|
|
|
+
|
|
|
+ .cui-cell {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ text-align: center;
|
|
|
+ font-size: 44rpx;
|
|
|
+ font-weight: 600;
|
|
|
+ color: black;
|
|
|
+ border-bottom: 1px solid #f5f5f5;
|
|
|
+ border-left: 1px solid #f5f5f5;
|
|
|
+ background-color: white;
|
|
|
+ box-sizing: border-box;
|
|
|
+ text-align: center;
|
|
|
+ background-color: #fafafa;
|
|
|
+ border-radius: 20rpx;
|
|
|
+
|
|
|
+
|
|
|
+ &:active {
|
|
|
+ filter: brightness(0.95);
|
|
|
+ transform: scale(0.95);
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ .cui-cell.border {
|
|
|
+ border-left: none;
|
|
|
+ }
|
|
|
+
|
|
|
+ .cui-cell.active {
|
|
|
+ background-color: #ccc;
|
|
|
+ }
|
|
|
+
|
|
|
+ .cui-cell {
|
|
|
+
|
|
|
+ &.operator,
|
|
|
+ &.percent,
|
|
|
+ &.backspace {
|
|
|
+ color: #FF7433
|
|
|
+ }
|
|
|
+
|
|
|
+ &.sign {
|
|
|
+ color: #FF7433
|
|
|
+ }
|
|
|
+
|
|
|
+ &.equal {
|
|
|
+ color: white;
|
|
|
+ background-color: #FF7433
|
|
|
+ }
|
|
|
+
|
|
|
+ &.clear {
|
|
|
+ color: #F75000;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .small {
|
|
|
+ .cui-calculator-title {
|
|
|
+ height: 60rpx;
|
|
|
+ line-height: 60rpx;
|
|
|
+ font-size: 25rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .cui-calculator-formula {
|
|
|
+ height: 40rpx;
|
|
|
+ line-height: 40px;
|
|
|
+ font-size: 22rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .col {
|
|
|
+ height: 45rpx;
|
|
|
+ line-height: 45rpx;
|
|
|
+ padding: 6rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .cui-cell {
|
|
|
+ font-size: 22rpx;
|
|
|
+ border-radius: 12rpx;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+</style>
|