Contact Information

KodeBlog

We're Available 24/ 7. Drop us an email.

Vue JS Components

Components are custom elements created using Vue that are similar to HTML elements. Componenents are named reusable Vue instances. Typically a component does a very specialized task that is often repeatitive. For example, your application might need to list products. Each product should contain an image, a title and description.

A Vue component can allow you to put the HTML of the product listing in a single place then you can use it as many times as possible. Since components are Vue instances, you can pass in the same parameters that you do when initialization a Vue instance. In this lesson, we will cover the basics of components in Vue

Topics to be covered

We will cover the following topics in this lesson

Lesson Prerequisites

For you to successfully complete this lesson, you should have the following requirements

  • NodeJS - this is mainly needed for development purposes only. You need NPM which comes with Node to work with tools like Vue CLI
  • Web Browser - a web browser can be used as an alternative to executing JavaScript files that we will be working with.
  • Visual Studio Code - we will be using it as the code editor. It comes with a built-in terminal that will allow us to easily execute JavaScript code from within the text editor. You can also use any code editor that you prefer.
  • JavaScript Basics - this is an added advantage and not mandatory. We will explain every piece of code covered in these lessons.
  • HTML & CSS Basics - this is an added advantage. Vue works on the HTML elements to manipulate them. The styling is done using CSS so you must be familiar with the basics

Lesson Practical Examples Project Setup

This is a practical based lesson. For you to successfully work out the examples given in this lesson, you will need to setup the following directories and files

Create a new directory called vue-components

Open the directory vue-components in Visual Studio Code or your favorite code editor

Create the following files inside your project folder.

  • index.html - this is the file that will contain our application source code

The following visualizes our project setup

vue-components
-index.html

How to Create a Vue Component

Creating components in Vue is similar to initializing a Vue instance with a few exceptions. Let's start with the syntax.

Syntax

Vue.component('component-name',{
    //initilization parameters
});

HERE,

  • Vue.component('component-name',{...}); We are calling the component method on the Vue obect. The component method accepts two parameters. The first parameter is the name of the component that you want to create and the second option is an object that has similar initilization parameters like the Vue instance.

Vue Components Hello World

Let's now look at a practical example. We will create a simple component that displays a message hello world in the browser.

Open the file hello.html and add the following code

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>VueJS Components Hello World</title>
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    </head>
    <body>
        <div id="root">
            <hello-item></hello-item>
        </div>

        <script type="text/javascript">
            Vue.component('hello-item',{
                template: `<p>Hello Vue Component</p>`
            });

            let vm  = new Vue({
                el: '#root'
            });
        </script>
    </body>
</html>

HERE,

  • Vue.component('hello-item',{...}); we define a component named hello-item. We have passed valid HTML code to the template parameter as a value.
  • let vm = new Vue({...}); we initialize an instance of Vue and bind it to the div with the id value of root.
  • <hello-item></hello-item> uses the Vue component just like any other HTML element

Open the file hello.html in the web browser. You should be able to get the following results

Hello Vue Component

Initialization Parameters

In the above example, we already looked at the parameter template. In this section, we will look at more parameters when creating a component. We will add the data and methods parameters. We will create a simple application that will allow the user to click on a component and the component will respond with a message that says you clicked me.

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>VueJS Components Hello World</title>
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    </head>
    <body>
        <div id="root">
            <hello-item></hello-item>
        </div>
        <script type="text/javascript">
            Vue.component('hello-item',{
                template: '<p v-on:click = "eventHandle()">{{message}}</p>',
                data : function(){
                    return {
                        message : "You haven't clicked me"
                    }
                },
                methods : {
                    eventHandle : function(){
                        this.message = "You clicked me"
                    }
                }
            });

            let vm  = new Vue({
                el: '#root'
            });
        </script>
    </body>
</html>

HERE,

  • Vue.component('hello-item',{...}) defines a component hello-item
  • template: '<p v-on:click = "eventHandle()">{{message}}</p>', defines a template that uses the paragraph HTML element. We are using the directive v-on:click to define a click event that will call the function eventHandle. {{message}} outputs the value of a variable message.
  • data : function(){...} defines a parameter data that is assigned to a function that returns an objected with a member of message.
  • methods : {...} defines another parameter method that returns an object.
  • <hello-item></hello-item> uses the component that we just created

The above example shows how we can pass multiple parameters when initialization a component. We use commands to separate multiple components.

Load the file params.html in the web browser

You should be able to get the following message

You haven't clicked me

Click on the above message, you should be able to get the following results

You clicked me

How to Reuse Components

Once a component has been defined, you can use it as many times as you want. In this section, we will use the example params.html and use our component three times like so.

<div id="root">
    <hello-item></hello-item>
    <hello-item></hello-item>
    <hello-item></hello-item>
</div>

The rest of the code remains the same. Open the file params.html in the browser. You should be able to see the following results.

You haven't clicked me
You haven't clicked me
You haven't clicked me

Click on any of the above paragraphs. It should be able to change to You clicked me while the rest of the components will display the original message. This is because each component that you use has its own instance data so it does not interfere with the other components that you have created from the same source.

Component Props

In the above examples, we were just displaying template data without passing in any data. In reality, a component that displays products will need to get the data from somewhere like the database or REST API. In this section, we will learn how to work with props.

Component props are like HTML attributes. For example, the anchor element <a href="#">Link</a> has an attribute of href that contains the link to navigate to. Component props are the same. For example, using our hello-item component, we can create an attribute name then say hello followed by the value of name.

Open the file props.html and add the following code to it.

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>VueJS Component Props</title>
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    </head>
    <body>
        <div id="root">
            <hello-item name="John"></hello-item>
            <hello-item name="Jane"></hello-item>
            <hello-item name="Jimmy"></hello-item>
        </div>

        <script type="text/javascript">
            Vue.component('hello-item',{
                template: '<p>Hello {{name}}</p>',
                props: [
                    'name'
                ]
            });

            let vm  = new Vue({
                el: '#root'
            });
        </script>
    </body>
</html>

HERE,

  • props: [...] we add an initilization parameter props that is an array containing only a single element name.
  • template: '<p>Hello {{name}}</p>', in our template definition, we are outputting the value of name which is coming from the props array
  • <hello-item name="John"></hello-item> uses the hello-item component and passes in the name of the person that we want to greet using the name attribute of our component. We are using our component three times using the names John, Jane and Jimmy.

Open the file props.html in the web browser. You should be able to get the following results

Hello John
Hello Jane
Hello Jimmy

Multiple props are separated using commas like so

props : [
    'name',
    'age',
    'gender'
]

Vue also allows you to specify the data types of props like so

props: {
  name: String,
  age: Number,
  single: Boolean,
  likes: Array,
  job: Object,
  describe: Function
}

Component Events

Componets can also be linked to events. We already looked at the click event in the previous sections. In this section, we will look at more examples. The anatomy of a component event is as follows

  • Use the v-on directive on the element to bind an event to it. The event could be click, mouseover, mouseout etc. For example, to bind a element to a click event, you can do it like v-on:click="handler" where handler is the function to be called when the event occurs
  • Define the event handler function in the component's methods section. The handler should be a function.

Let's create a simple button that counts the number of times that it has be clicked.

Open the file events.html and add the following code to it

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>VueJS Component Events</title>
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    </head>
    <body>
        <div id="root">
            <clickable-button></clickable-button>
        </div>

        <script type="text/javascript">
            Vue.component('clickable-button',{
                template: '<button v-on:click="incrementCount">The click count is: {{count}}</button>',
                data: function(){
                    return {
                        count: 0
                    }
                },
                methods: {
                    incrementCount: function(){
                        this.count++;
                    }
                }
            });

            let vm  = new Vue({
                el: '#root'
            });
        </script>
    </body>
</html>

HERE,

  • Vue.component('clickable-button',{...} defines a Vue component named clickable-button
  • template: '<button v-on:click="incrementCount">...</button> defines the template for our button which is basically a button with a click event that calls the function incrementCount. Inside the button, we are outputting the value of the data member count
  • data: function(){...} defines a data member count that is initialized to the value 0.
  • methods: {...} defines a function incrementCount inside methods parameter. The function simply increments the value of count using this.count++;.
  • <clickable-button></clickable-button> displays our component inside the div with the id of root.

Open the file events.html in the browser

You should be able to get the following results

{{image place holder}}

Try clicking on the button. You should be able to see the click count value starting going up.

Let's look at another example, we will create a second component that will display the message Reveal Secret which if the mouse moves over it will diplay the message I love You. When the mouse oves out, the message will return to the original one.

Open the file events.html in Visual Studio Code and define the following component just below our clickable-button

Vue.component('secret-message',{
    template: '<h4 v-on:mouseover="revealSecret" v-on:mouseout="hideSecret">{{message}}</h4>',
    data: function(){
        return {
            message: "Reveal Secret"
        }
    },
    methods: {
        revealSecret: function(){
            this.message = "I Love You";
        },
        hideSecret: function(){
            this.message = "Reveal Secret";
        }
    }
});

HERE,

  • Vue.component('secret-message',{...} defines a component secret-message
  • template: '<h4 v-on:mouseover="revealSecret" v-on:mouseout="hideSecret">{{message}}</h4>' defines a templates that uses the h4 element to display the value of the variable message. We have attached 2 events to the component mouseover, and mouseout. Our events have revealSecret and hideSecret as event handlers.
  • revealSecret: function(){...} defines the function that responds to the mouseover event
  • hideSecret: function(){...} defines the function that responds to the mouseout event

Now add the following line inside the div with the id of root just below the clickable-button component

<secret-message></secret-message>

Load the file in the browser, try to move the mouse over the message Reveal Secret and watch the magic happen.

Component Lifecycle Hooks

The creation of a component goes through a number of stages and Vue allows you to define specific actions to take at each stage using hooks. Components are Vue instances so the lifecycle hooks associated with Vue instances also apply to components. We have

  • created - fired when the component instance is created
  • mounted - fired when the component is mounted
  • updated - fired when the data is updated
  • destroyed - fired when the component instance is desroyed

In the previous lesson on Vue Instances, we alread covered hooks in detail so if you are would like to know more about hooks then you can read the article on Instances.

Let's work with a simple example that displays a list of fun to do things

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>VueJS Component Props</title>
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    </head>
    <body>
        <div id="root">
            <todo-item item="Buy Wine"></todo-item>
            <todo-item item="Drink Wine"></todo-item>
            <todo-item item="Be Happy"></todo-item>
        </div>

        <script type="text/javascript">
            Vue.component('todo-item',{
                template: '<li>{{item}}</li>',
                props: [
                    'item'
                ],
                created: function(){
                    console.log(`Component ${this.item} has been created`);
                },
                mounted: function () {
                    this.$nextTick(function () {
                        console.log(`The component has been mounted successfully`);
                    })
                },
                updated: function () {
                    this.$nextTick(function () {
                        console.log(`Vitual DOM has be re-rendered due to data change`);
                    })
                },
                destroyed: function(){
                    console.log('The vm instance has been destroyed at point blank');
                }
            });

            let vm  = new Vue({
                el: '#root'
            });
        </script>
    </body>
</html>

HERE,

  • created: function(){...} defines the function that should be called when the component is created
  • mounted: function(){...} defines the function that should be called when the component is mounted
  • updated: function(){...} defines the function that should be called when the component is updated
  • destroyed: function(){...} defines the function that should be called when the component is destroyed

Open the file hooks.html in the browser then open developer tools and go to the console tab

You should be able to see the following messages

Component Buy Wine has been created
Component Drink Wine has been created
Component Be Happy has been created
3 The component has been mounted successfully

Components X-Template

So far we have been working with component templates directly when defining the components. For simple examples like what we are working with that is cool. But when you have to work on real world applications, components can have a good number of HTML code.

Vue allows you to define the template inside a script element with type of text/x-template that can have a unique id and your HTML markup. Inside the component template parameter, you can just reference the id of your x-template.

A template can only contain a single root elements and as many nested elements inside as needed. The following is an example of a valid template

<div>
    <h1>Title</h1>
    <p>Paragraph sentence</p>
</div>

The following is not valid

<h1>Title</h1>
<p>Paragraph sentence</p>

Let's now look at how that works.

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>VueJS Components X-Template</title>
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    </head>
    <body>
        <div id="root">
            <todo-item></todo-item>
        </div>

        <script type="text/x-template" id="items-template">
            <div>
                <ol>
                    <li>Make new year resolutions</li>
                    <li>Procastinate the whole year</li>
                    <li>Look forward to next year</li>
                    <li>Repeat process in next year</li>
                </ol>
            </div>
        </script>

        <script type="text/javascript">
            Vue.component('todo-item',{
                template: '#items-template'
            });

            let vm  = new Vue({
                el: '#root'
            });
        </script>
    </body>
</html>

HERE,

  • <script type="text/x-template" id="items-template"> defines our x-template that contains our HTML markup. Note the HTML is wrapped in a single root element
  • template: '#items-template' references the id of our x-template when defining our component

Components Scope

Vue components have either global or local scope. Global components are available to all instances of Vue while local components have to be bound to an instance for them to be available to it.

Global Components

Global components are available to all running instances of Vue. Global components are created directly on the Vue object like so.

Vue.component('global-component',{
    template: '<p>Global Component</p>'
});

We then define a Vue instance as follows

let vm  = new Vue({
	el: '#root'
});

We do not need to explicitly bind the component to the instance vm that we created. It is already made available to it. The above examples have been working with global scope so we will not provide a complete working example in this section.

Local Components

Local components have to be explicitly bound to a particular instance for them to be available. This is usually the best approach when working with components if you know that the particular component is only needed by very spefici instances only.

The following example shows how to create components locally

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>VueJS Local Components</title>
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    </head>
    <body>
        <div id="root">
            <hello-item></hello-item>
        </div>

        <script type="text/javascript">
            let helloComponent = {
                template: '<p>{{message}}</p>',
                data : function(){
                    return {
                        message : 'I am a local component'
                    }
                }
            }

            let vm  = new Vue({
                el: '#root',
                components: {
                    'hello-item' : helloComponent
                }
            });
        </script>
    </body>
</html>

HERE,

  • let helloComponent = {...} defines an object variable that contains valid component initialization parameters. We have the template and data parameters just like we did with global variables.
  • components: { 'hello-item' : helloComponent } defines a component hello-item in the components parameter of the instance intiliazation. The component hello-item is assigned the value of the component object that we created and stored in the variable helloComponent.
  • <hello-item></hello-item> utilizes the local component that we just created.

Run the above program should give you the following results

I am a local component

Summary

Vue components are reusable named Vue instances that perform specific tasks. The component should have a name, a template that is made up of HTML elements among others and it can optionally have data, methods, hooks etc. You can use components to create navigation menus, sidebar widgets, lists etc. Global components are available to all instances while local components only belong to the particular instance where they are defined.

Author: Rodrick Kazembe

Rodrick is a developer who works on Desktop, Web and Mobile Applications. He is familiar with Python, Java, JavaScript, C++, C#, Kotlin, PHP, Python and the list goes on. Rodrick enjoys sharing knowledge especially when it comes to technology.

Vue JS Directives

VueJS Templates

Leave A Reply