An Interest In:
Web News this Week
- April 1, 2024
- March 31, 2024
- March 30, 2024
- March 29, 2024
- March 28, 2024
- March 27, 2024
- March 26, 2024
Simple Calculator using Vue and Bootstrap 5
The HTML Markup
Bootstrap 5 provides all the UI styling and responsive behavior. It's a great fit with Vue now that it's no longer dependent on jQuery. The Bootstrap grid row
& col-*
are used to responsively change the calculator width as screen size changes.
<div class="row"> <div class="col-xxl-2 col-lg-3 col-md-4 col-sm-6 mx-auto bg-dark rounded-3 shadow-sm p-3"> <input class="form-control form-control-lg text-success" v-model="calculator.displayValue" /> <!-- calculator number pad using grid --> <div class="row g-0 text-center mt-2"> <div class="col-auto text-white"> <div class="row g-1 g-lg-1"> <div v-for="(key,i) in keypad" :key="i" class="ms-auto col-3 py-2"> <button class="btn btn-dark text-warning w-100" @click="processKey(key.value)">{{ key.label }}</button> </div> <div class="col-12 pt-2"> <button class="btn btn-dark border-secondary btn-lg text-warning w-100 fw-bold lead" @click="processKey('=')">=</button> </div> <div class="col-12"> <div v-if="errValue" class="alert alert-warning p-2 text-truncate small" role="alert"> {{ errValue }} </div> </div> </div> </div> </div> </div> </div>
The Vue App Data
Calculator state is kept in it's own data calculator
object to track the displayValue
, firstOperand
and operator
. waitingForSecondOperand
let's us know when it's ready to perform a calculation.
The keypad
array is ordered by how I wanted the keys to render as columns inside the Bootstrap row
...
<div v-for="(key,i) in keypad" :key="i" class="ms-auto col-3 py-2"> <button class="btn btn-dark w-100" @click="processKey(key.value)">{{ key.label }}</button></div>
... data () { return { calculator: { displayValue: '0', firstOperand: null, waitingForSecondOperand: false, operator: null, }, errValue: null, keypad: [ {label:'7', value: 7}, {label:'8', value: 8}, {label:'9', value: 9}, {label:'x', value: '*'}, {label:'4', value: 4}, {label:'5', value: 5}, {label:'6', value: 6}, {label:'+', value: '+'}, {label:'1', value: 1}, {label:'2', value: 2}, {label:'3', value: 3}, {label:'-', value: '-'}, {label:'AC', value: 'AC'}, {label:'.', value: '.'}, {label:'0', value: 0}, {label:'/', value: '/'}, ], },...
The Vue App Methods
Of course the calculator actually needs to calculate so I define a series of methods to watch the keystrokes and perform basic math functions. Most of them should be self-explanatory. You will see that errValue
is used to store any errors, and resets upon keypress or clear.
When a key is pressed, processKey()
is called to determine which key and then call the appropriate function...
inputDigit()
- when any digit is clickedhandleOperator()
- when any operator is clickedequalPressed()
- when the equal sign is clickedinputDecimal()
- to handle the decimal point (.)resetCalculator()
- to clear the calculator ('AC')
... methods: { processKey: function(val) { this.errValue = null switch (val){ case "AC": this.resetCalculator() break; case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: this.inputDigit(val) break; case "+": this.handleOperator("+") break; case "-": this.handleOperator("-") break; case "/": this.handleOperator("/") break; case "*": this.handleOperator("*") break; case "=": this.equalPressed(); break; case ".": this.inputDecimal(".") break; default: this.errValue = 'KEY ERROR: in default' } }, equalPressed() { const { firstOperand, displayValue, operator } = this.calculator try{ this.calculator.displayValue = this.calculate(firstOperand, displayValue, operator) } catch (e){ this.errValue = e } }, inputDigit(digit) { const { displayValue, waitingForSecondOperand } = this.calculator console.log(waitingForSecondOperand) if (waitingForSecondOperand === true) { this.calculator.displayValue = digit this.calculator.waitingForSecondOperand = false } else { console.log(displayValue) this.calculator.displayValue = displayValue === '0' ? digit : displayValue + '' + digit } }, inputDecimal(dot) { const { displayValue, waitingForSecondOperand } = this.calculator if (waitingForSecondOperand === true) { this.calculator.displayValue = '0.' this.calculator.waitingForSecondOperand = false return } // check for existing decimal if (displayValue % 1 === 0) { this.calculator.displayValue += dot } }, handleOperator(nextOperator) { const { firstOperand, displayValue, operator, waitingForSecondOperand } = this.calculator const inputValue = parseFloat(displayValue) if (operator && waitingForSecondOperand) { this.calculator.operator = nextOperator return } if (firstOperand == null && !isNaN(inputValue)) { this.calculator.firstOperand = inputValue } else if (operator) { const currentValue = firstOperand || 0 const result = this.calculate(currentValue, inputValue, operator) this.calculator.displayValue = String(result) this.calculator.firstOperand = result } this.calculator.waitingForSecondOperand = true this.calculator.operator = nextOperator }, calculate(firstOperand, secondOperand, operator) { if (operator === '+') { return firstOperand + secondOperand } else if (operator === '-') { return firstOperand - secondOperand } else if (operator === '*') { return firstOperand * secondOperand } else if (operator === '/') { if (secondOperand == 0){ this.errValue = 'ERROR: Cannot divide by 0' } else { return firstOperand / secondOperand } } return secondOperand }, resetCalculator() { this.calculator.displayValue = '0' this.calculator.firstOperand = null this.calculator.waitingForSecondOperand = false this.calculator.operator = null }, },...
As always, you can play with the latest Bootstrap 5, and find more handy Vue snippets and examples on Codeply!
Thanks for reading!
Original Link: https://dev.to/codeply/simple-calculator-using-vue-bootstrap-5-27bn
Dev To
An online community for sharing and discovering great ideas, having debates, and making friendsMore About this Source Visit Dev To