Build A Unit Converter with Vue.js

Please note that this post may contain affiliate links, and for every purchase you make, at no extra cost to you, a commission fee will be rewarded to me.

In this article, we’ll talk about the basics of Vue.js template syntax by building a simple unit converter. And since our focus of Vue.js and not JavaScript, we’ll use this JS package to keep things simple: https://github.com/ben-ng/convert-units

Create A New Vue Component

In the resources/js/components, create a new Vue component:

UnitConverter.vue

<template>

</template>

<script>
    export default {
        name: "UnitConverter"
    }
</script>

<style scoped>

</style>

And Then, we need to register it in the app.js file:

Vue.component('unit-converter', require('./components/UnitConverter.vue').default);

Now, let’s test to see if it works, add something in the template section:

<template>
    <div id="unit-converter">
        <p>Unit Converter</p>
    </div>
</template>

Open the browser and go to http://127.0.0.1:8000/tools/unit-converter

Vue Template Syntax

Text Interpolation

Text interpolation is the most basic form of data binding.

<span>Message: {{ msg }}</span>

The mustache tag (double curly braces) will replace the value of the msg property on the corresponding data object. It will also be updated whenever the data object’s msg property changes.

Directives

Here I will only introduce several basic directives that we are going to use in this tutorial, but if you are interested, you can read the official guide for a full list of derectives in Vue.js: https://vuejs.org/v2/api/#Directives

v-bind

If you wish to make changes to HTML attributes, you need to use the v-bind directive instead, since mustaches will not work inside HTML attributes.

<div v-bind:id="dynamicId"></div>

In the case of boolean attributes, where their mere existence implies truev-bind works a little differently. In this example:

<button v-bind:disabled="isButtonDisabled">Button</button>

If isButtonDisabled has the value of nullundefined, or false, the disabled attribute will not even be included in the rendered <button> element.

v-on

v-on is probably the most commonly used vue directive in your project, it listens to DOM events and reacts accordingly.

<a v-on:click="doSomething"> ... </a>

For example, when you click on this HTML element, it will invoke the doSomething() function.

Here is a list of all the DOM events that you can use: https://www.w3schools.com/jsref/dom_obj_event.asp

v-model

v-model is another useful vue directive used for form input binding. For example:

<input v-model="message" placeholder="edit me">
<p>Message is: {{ message }}</p>

The first line of code will create a input form, and when you type in it, the value of message will be updated accordingly. The change will be reflected below, after “Message is:”.

v-if & v-for

These two directives works just like the if statement and for loops in any other frameworks and languages. Here are some examples:

<h1 v-if="awesome">Vue is awesome!</h1>
<h1 v-else>Oh no 😢</h1>
<ul id="example-1">
  <li v-for="item in items" :key="item.message">
    {{ item.message }}
  </li>
</ul>

Design Unit Converter

For the sake of simplicity, we’ll use only Bootstrap to design our unit converter.

HTML Template

<template>
    <div class="unit-converter">
        <nav>
            <div class="nav nav-tabs" id="basic-tab" role="tablist">
                <a class="nav-item nav-link active" id="length-tab" data-toggle="tab" href="#length" role="tab"
                   aria-controls="nav-length" aria-selected="true">Length</a>
            </div>
        </nav>
        <div class="tab-content" id="basic-tabContent">
            <div class="tab-pane fade show active" id="length" role="tabpanel" aria-labelledby="length-tab">
                <div class="row">
                    <div class="col m-3">
                        <p>From:</p>
                        <div class="input-group">
                            <input v-model="input" v-on:change="convert()"
                                   type="text" class="form-control col-8"
                                   aria-label="Text input with segmented dropdown button">
                            <select v-model="fromUnit" v-on:change="convert()"
                                    class="custom-select col-4" id="lengthFromSelect"
                                    aria-label="Example select with button addon">
                                <option disabled value="">select unit</option>
                                <option value="mm">millimeter(mm)</option>
                                <option value="cm">centimeter(cm)</option>
                                <option value="m">meter(m)</option>
                                <option value="km">kilometer(km)</option>
                                <option value="in">inch(in)</option>
                                <option value="ft">foot(ft)</option>
                                <option value="yd">yard(yd)</option>
                                <option value="mi">mile(mi)</option>
                            </select>
                        </div>
                    </div>
                    <div class="col m-3">
                        <p>To:</p>
                        <div class="input-group">
                            <input v-bind:placeholder="result"
                                   type="text" class="form-control col-8"
                                   aria-label="Text input with segmented dropdown button" disabled>
                            <select v-model="toUnit" v-on:change="convert()"
                                    class="custom-select col-4" id="lengthToSelect"
                                    aria-label="Example select with button addon">
                                <option disabled value="">select unit</option>
                                <option value="mm">millimeter(mm)</option>
                                <option value="cm">centimeter(cm)</option>
                                <option value="m">meter(m)</option>
                                <option value="km">kilometer(km)</option>
                                <option value="in">inch(in)</option>
                                <option value="ft">foot(ft)</option>
                                <option value="yd">yard(yd)</option>
                                <option value="mi">mile(mi)</option>
                            </select>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>

Here, we’ll have four different variables bound with four different HTML elements. On line 15, we use the v-model directive to bind the input variable since the element is an input form.

From line 18 to 30, we define a select form and bind the fromUnit variable to it. But unlike the regular input form, we also need to add a value for each option.

And on the result side, we first disable the input form, since we only need to show the result of the conversion, and we don’t want the user to be able to alter it. Next, on line 36, we bind the result variable to the disabled input form’s placeholder using v-bind:placeholder.

Finally, we need to add event listeners to the select forms and the input form using v-on directive and change event. Like the line 15, 18 and 39. This means whenever the value of these forms changes, the convert() method will be triggered. And we will define these variables and methods in the script section of our vue file.

JavaScript Code

Let’s first install the npm package that we need to use in this tutorial. Run the following command:

npm install convert-units --save
<script>
    const units = require('convert-units');

    export default {
        name: "UnitConverter",
        data() {
            return {
                result: "",
                input: "",
                fromUnit: "",
                toUnit: "",
            }
        },
        methods: {
            convert() {
                this.result = `${units(this.input).from(this.fromUnit).to(this.toUnit)}`;
            },
        }
    }
</script>

In the data section, we define the four variables we talked about. And in the methods section, we define the convert method. `${...}` will turn the result into a string.

In the next article, we’ll try something more challenging, building a word counter, and we’ll talk about the life cycle of Vue.js.

Leave a Reply

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