Javascript - Javascript - VueJS

Number System Application using Vue JS

Vue Number System Application


This tutorial will take us through the phase of building a full functioning number system conversion application using Vue Js.

This tutorial assume you are familiar with

  1. vue js cli application, you can come back after going through this tutorial on how to get started with Vue js cli application.
  2. Vue js custom com

Let’s go on!.

Open your node js command prompt and navigate to your project folder.

cd vue-projects

Run

npm install -g vue-cli

If vue cli install successful, you should get a message like the one in the image below.

Now, everything is ready to start building our applications Ensure you are in the folder where you want your application to reside and type the following command:

vue init webpack number-converter

It will ask you several questions. Enter the project name and choose the default answer and hit Enter, for the rest of the questions. After the initialization, you are ready to install and run your application:

To test our application, run

cd number-converter
npm install
npm run dev

If everything is fine, the following page will automatically open in your default browser:

Vue js default page

All that being done, let’s get started to the our main application.

Open your number-converter folder in your favourite editor and locate the app.vue from the src folder. Delete the source code there leaving only the ones shown below.

 <template>
  <div id="app">
    
  </div>
</template>

export default {
  name: 'App'
}

#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}

Now, if you hit the save button, you would see that your browser will automatically be refreshed with a blank page.

Howvere, our final Vue application will look like this.

Number converter in Vue Js

So, we will be having 2 more components for our application.

  1. The selection component to allow toggle of conversion mode
  2. The second component which will be the main engine which will handle user input, conversion as well as displaying the output to users.

To begin, let’s add some properties to our data object in the App.vue component.


export default {
name: 'App',
data () {
return {
binaryValue: 0,
decimalValue: 0,
conversionType: 'btd',
options: [{
'type': 'btd',
'name': 'Binary to Decimal'
}, {
'type': 'dtb',
'name': 'Decimal to Binary'
}]
}
}
}

You’ll get to know why we added the properties as we go on with the application. Now, let’s create a mode.vue component. and add the following code

Take a look at what we did, we have created a new vue component and give it a name of Mode, then we will have to import this component locally in our App.Vue file so as to be able to use it.

Edit your App.vue file to


import Mode from './mode'

export default {
  name: 'App',
  components: {
    'Mode' : Mode
  },
  data () {
  return {
    binaryValue: 0,
    decimalValue: 0,
    conversionType: 'btd',
    options: [{
        'type': 'btd',
        'name': 'Binary to Decimal'
      }, {
          'type': 'dtb',
          'name': 'Decimal to Binary'
      }]
  }
}
}

We have been able to import our mode.vue component into how app.vue which means we can just output the content of our mode.vue app using inside the


<div id="app"> </div>

tag in our app.vue so we have


<div id="app"> <Mode>  </Mode> </div>

With that, we have our selection mode appear in the browser

 

Oh, that’s great but let’s add some styling to our codes. Go to your app.vue file and add the following CSS codes to the style tag.

 


* {
    box-sizing: border-box;
}
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}

body {
    background-color: #000;
    color: #fff;
}
.container {
    height: 100vh;
    text-align: center;
    padding-top: 20vh;
}
.options select {
    height: 40px;
    width: 50vw;
}
.inner-container {
    color: #fff;
    width: 70vw;
    height: 60vh;
    margin: auto;
    display: flex;
    align-items: center;
    justify-content: space-around;
}
.box {
    display: flex;
    align-items: center;
    justify-content: space-around;
    width: 45%;
    height: 250px;
    background-color: #eee;
    text-align: center;
    color: #000;
}
input {
    height: 40px;
}
button {
    height: 40px;
    background-color: blue;
    border: 0;
    color: #fff;
    padding: 8px;
}
.decimal-val {
    background-color: rgba(0, 0, 0, .7);
    padding: 10px;
    min-width: 70%;
    margin: auto;
}

 

I’ve added some styling that currently not yet used but we still make use of them in our application. Now that our application is looking fine, Let’s add some interaction to our Mode.vue component so that it can listen to the App.vue file for the options, report changes made to the select option back to our app.vue component.

In your App.vue component, edit the template file to


<template>
  <div id="app">
    
   <mode :options="options" :conversion-type="conversionType" @conversion-mode="changeConversion($event)"> </mode>
   
 </div>
</template>

We have used the v-bind ( : as shorthand) to bind the options and conversionType to our mode.vue component and also used the v-on (@ as shorthand) to listen to an event from our mode.vue component. Again we asked our app.vue component to invoke the changeConversion method, passing the value emitted by the mode.vue component. Now, let’s modify our mode.vue component to

The template tag will be


<template>
<div class="options">
    <h2> Conversion Mode</h2>
    <select v-model="conversionType" @change="$emit('conversion-mode',conversionType)">
        <option :value="option.type" v-for="option in options" :key="option.type">
          {{ option.name }}
        </option>
    </select>
  </div>
</template>

and our script tag will be


export default {
  name: 'Mode',
  props: ['options','conversion-type']
}

Changes.

  1. I have added the props property to listen to the attributes that were passed to the mode tag when used in the app.vue component.
  2. I have used the v-for directive to iterate the property of the options object
  3. I have used the @change to listen to changes that occur when a user selects a new value from the select box.

Hit the save and our application is fine, You might now notice any difference when you change the option value and that’s because we didn’t output convesionType. Don’t worry, let’s move on to the next component which is the engine that does the conversion

Let’s create a converter.vue file and add the following codes


<template>
  <div class="inner-container">
    <div class="box">
      <div>
        <h3>
          {{ fromText }}
        </h3>
        <input type="text" v-model="fromVal">
        <button @click="convertNumber()">Convert
      </div>
    </div>
    <div class="box">
     <div>
        <h3>
          {{ toText }}
        </h3>
        <p class="decimal-val">
            {{ toVal }}
       </p>
      </div>                    
    </div>
  </div>
</template>

It’s pretty simple, I have asked my component to output some data, bind the input box to a data property and and invoke a method if the convert button is clicked. Now let’s add the script tag and put the following.


name: 'Mode',
  props: ['binaryValue', 'decimalValue', 'conversionType'],
    data() {
        return {
            fromVal: 0,
            fromText: 'Binary Value',
            toVal: 0,
            toText: 'Decimal Value',
            conversionType: 'btd'
        }
    }

I have added the props for my component to look up to the properties that were passed to it and also added some properties to my data object as default value, which will change as user interacts with the application.

Now, let’s respond to user input and compute our number conversion using the following algorithms.

  1. If the conversion is from Binary to Decimal, Then multiply each number by 2 raised to the power of its index when the index is counted backward.
  2. If the conversion is from Decimal to Binary, then divide the number by 2 saving the modulo value in a variable until the inputted number becomes 0

Now, let’s modify our script tag to


export default {
  name: 'Convert',
  props: ['binaryValue', 'decimalValue', 'conversionType'],
    data() {
        return {
            fromVal: 0,
            fromText: 'Binary Value',
            toVal: 0,
            toText: 'Decimal Value',
            conversionType: 'btd'
        }
    }
    methods: {
        convertNumber: function() {
            var ans;
            var len = this.fromVal.length;
            if (this.conversionType == 'btd') {
                let ans = 0;
                for (var i = 1; i <= len; i++) {
                    ans += (Number(this.fromVal[i - 1]) * 2) ** (Number(this.fromVal.length) - Number(i));
                }
                this.toVal = ans;
                ans = 0;
                this.$emit('updatedecimal', this.toVal);
            } else {
                let ans = '';
                while (Number(this.fromVal) > 0) {
                    this.fromVal = parseInt(Number(this.fromVal) / 2);
                    ans += (Number(this.fromVal) % 2);
                }
                this.toVal = ans;
                ans = '';
                this.$emit('updatebinary', this.toVal);
            }
        }
    }
}

What I did was to implement the conversion algorithm above, consider checking this article for explanations on number system. I’ve also emitted the new binary and decimal value to the parent component which is our App.vue.

Now, let’s test our Application

Play around with the application, and you will see that our application is working fine but with one thing left, the application is not responding to change in the conversion mode. So, let’s deal with that. Let’s watch for changes in the value. Add the edit your script tag in converter.vue component to


export default {
  name: 'Convert',
  props: ['binaryValue', 'decimalValue', 'conversionType'],
    data() {
        return {
            fromVal: 0,
            fromText: 'Binary Value',
            toVal: 0,
            toText: 'Decimal Value',
            conversionType: 'btd'
        }
    },
    watch: {
        conversionType: function(newvalue) {
            this.fromVal = 0;
            this.toVal = 0;
            this.toText = newvalue;
            if (newvalue == 'btd') {
                this.fromText = 'Binary Value';
                this.toText = 'Decimal Value';
            } else {
                this.fromText = 'Decimal Value';
                this.toText = 'Binary Value';
            }
        }
    },
    methods: {
        convertNumber: function() {
            var ans;
            var len = this.fromVal.length;
            if (this.conversionType == 'btd') {
                let ans = 0;
                for (var i = 1; i <= len; i++) {
                    ans += (Number(this.fromVal[i - 1]) * 2) ** (Number(this.fromVal.length) - Number(i));
                }
                this.toVal = ans;
                ans = 0;
                this.$emit('updatedecimal', this.toVal);
            } else {
                let ans = '';
                while (Number(this.fromVal) > 0) {
                    this.fromVal = parseInt(Number(this.fromVal) / 2);
                    ans += (Number(this.fromVal) % 2);
                }
                this.toVal = ans;
                ans = '';
                this.$emit('updatebinary', this.toVal);
            }
        }
    }
}

What changed? We placed a watch on the conversionType data and toggle between conversion mode in our application.

That’s pretty great, we have our full number system conversion application working.

 


3 comments on "Number System Application using Vue JS"

  • ok, good job

    Zainab wrote on
  • Thank you. I really found this helpful

    Frank wrote on
  • Wow, this tutorial is really interesting. Now, I can do something apart from the usual hello world application .

    Samuel wrote on

Leave a Reply

Your email address will not be published. Required fields are marked *