Components in VueJs
Tags: vue, javascript, components
Published: 2018-06-06 18:59:14

---
title: Components in VueJs
published: true
description: How components in Vue Js work and how best to use them.
tags: vue, javascript, components
---

Components make our codes reusable and enable us to stick to the software development principle of D.R.Y (Don’t Repeat Yourself).  Components are blocks of code which extend basic HTML markup behaviour and can be used over and over for different purposes. What this means is that components in Vue look like basic HTML elements, but they are more configurable and hence, can perform more functions than a plain HTML element. Components can also contain other components, this makes our front end very robust and quite modular.

Modern web applications are composed of many parts, and the best way to keep track of all the moving parts would be to abstract them into different small parts (components), making them easy to structure, use and maintain. So that in the end, you might end  up with code similar to this for an entire page, that performs a lot of functions:

```html
    

<html>
  <head>
    <script src='https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.js'></script>
  </head>
  
  <div id='app'>
    <app-header :links="links"></app-header>
    <app-sidebar :items="items"></app-sidebar>
    <app-body></app-body>
    <app-footer></app-footer>
  </div>
</html>    

```

You’d agree with me that as a maintainer, code like this is very neat and straight to the point, and it would not take too much time to figure out what’s going on and what section does what.

Components in Vue can be created in two ways, they can be created in a separate file, then imported using the Es6  `import` statement. Or they can be registered inside the base JavaScript file and used directly.

For the purpose of this article, we are going to create a basic component that takes in a user object, outputs a list, and alerts the user details when each user is clicked. 
With this, we will demonstrate:


1. Creating Components,
2. Passing Data to components via Props,
3. List Rendering,
4. Emitting events from a child component,
5. Listening for events on a parent component, and
6. Handling Emitted events

If you are new to Vue, you can check out the [Official Documentation](https://vuejs.org/v2/guide/) to get started.

If you'd like to skip on ahead to the finished project, there's a [Code pen](https://codepen.io/faradayyg/pen/gKwpqQ) where the finished project is hosted.


##Setting Up

There are two ways to setup your Vue project. 

1. Using the Webpack build tool or
2. Using Vue via the Vue CDN. 

Let us explore defining our components inside our JavaScript file, using the Vue CDN.

To get started, make a plain old HTML File, and include the Vue JavaScript file from the CDN. 

```html 
<script src='https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.js'></script>
```

This makes sure that Vue is available in the project. Next, we add a `<script>` tag inside the body tag. This is where our Code will live.

By now, Your Project should look like this:

```html

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <script src='https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.js'></script>
</head>
<body>   

    <script type="text/javascript">
      //Our Codes, Here            
    </script>
</body>
</html>
```

We are now ready to begin writing our code. 
Just to make sure that Vue Js is properly installed, let’s create a “Hello Vue” application.
Add a div tag within the body tag of your HTML file, give it an id of “app". 
Within the `div` tag, copy and paste this:  `{{message}}` the text in the double curly braces indicate a variable in Vue.

Within your script tag, copy and paste the following, we will explore what these mean in a moment.

```javascript

let app = new Vue({
    el : "#app",
    data(){
      return{
        message: 'Hello Vue'
        }
    }
});
```

What we have done above is, 

1. Instantiate a new Vue Object, telling it that the HTML element it should use, has an ID of `app`
2. We have then provided a data object, that returns `message`
3. Finally, we printed out the message variable defined in the data object above, into the HTML by typing in this: `{{message}}` the double curly braces indicate that their content is a variable. 

By now, our entire Code Should look like this:

```html

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <script src='https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.js'></script>
</head>
<body>

    <div id="app">
            {{message}}
    </div>
    <script type="text/javascript">
       let app = new Vue({
           el : "#app",
            data(){
              return{
                 message: 'Hello Vue'
              }
            }
       });

    </script>

</body>
</html>
```
If we run this in the browser, we should get an output of “Hello Vue”.
Now that we have confirmed that Vue is properly setup, let’s get right to defining components in Vue.

##Defining Our Component.

As previously stated, components can be created as a separate file altogether, or directly inside our main JavaScript file. For this tutorial, we are going to be defining our components directly inside our JavaScript file.

Components are registered using  `Vue.component(``'``tag-name``'``, options)` command, where `tag-name`  is the name that you want your component to bear and `options` is an object that defines the behaviour of the component. This makes the component globally available within the file and thus, can now be used in different cases.

Let’s start by defining a dummy component that does nothing but show a message on the screen. Let’s call this `user-list`. To follow along, create a new HTML file, or modify the "hello vue" file to look like this:

```html

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <script src='https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.js'></script>
</head>
<body>

    <div id="app">
      <user-list></user-list>
    </div>

    <script type="text/javascript">

      let userList = Vue.component('user-list', {
      template : '<div>I am a component</div>'
      
      });

       let app = new Vue({
           el : "#app"
          
       });

    </script>

</body>
</html>
```

What we have done is create a Vue component, named it “user-list” and then within our HTML, we have used `user-list` like a normal HTML tag. This is how you output your component to the front end.
 You can see the `template` attribute in the Vue component definition, this specifies the HTML tags that will be output by the component when mounted. Take note, that a Vue component can only have one root element.
That’s all there is to creating a basic component in Vue. 

![Our Component](https://res.cloudinary.com/ddbm6rq61/image/upload/v1528310225/1.png)

Although this works, it is not very useful as it does not demonstrate the power and reusability of components. Let’s extend this component further by defining props. 


##Props and Components

Each Vue component lives in a scope of its own and should not access data from the outside.
Props give us a means of passing data from a parent component (outside), to a child component. In our case, we will be passing data from `app` to the  `userList` component. But before we can do this, we have to explicitly specify the props we are expecting in our `user-list`  component. Add another attribute to the `user-list` component, call it `props` this will be an array of all the props we are expecting to be passed to the `user-list` component. Let the content of the props attribute be `['users']` While we are at it, let’s modify the `template` attribute, and remove all contents of the `div`  replacing them with `{{users}}`.

Also in the main HTML file, let’s add a new attribute called “users” to the `<user-list>` tag, and set the value to `users=``"``list of users``"`.

Right now, our app’s source code should look somewhat like this: 

```html

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <script src='https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.js'></script>
</head>
<body>

    <div id="app">
      <user-list users="list of users"></user-list>
    </div>

    <script type="text/javascript">

      let userList = Vue.component('userList', {
      template : '<div>{{users}}</div>',
      props: ['users']
      
      });

       let app = new Vue({
           el : "#app"
          
       });

    </script>

</body>
</html>
```

If everything works correctly, the output should be this: 
![Displaying data passed as Prop](https://res.cloudinary.com/ddbm6rq61/image/upload/v1528310222/2.png)

As we can see, our component has become a little smarter, data can now be passed from the parent to it, using `users` attribute. 

This does not mean that only strings can be passed as props, variables can be passed as well, using the `v-bind` Vue attribute. Let’s extend things a little further. In our main Vue app, we will define a data attribute and pass in the variable which will be used by the Vue component. The data attribute will now be this:

```javascript

         data(){
            return{
              allUsers : [
                {
                  name : 'John Doe',
                  about : 'Really nice guy'
                },
                {
                  name : 'Jane Dean',
                  about: 'Loves eggs'
                },
                {
                  name : 'Clark Kent',
                  about: 'Not your everyday reporter'
                }
              ]
            }
           }
```


This basically just returned an array of three objects with two keys each,  `name` and `about`. 
To pass our newly defined list of users to the component, we simply add the `v-bind:users` attribute to the component, and pass the name of the array to it, hence we have `<user-list v-bind:users=``"``allUsers``"``></user-list>` . The `v-bind:` prefix tells Vue that we want to dynamically bind the `users` props to a variable, and not pass in a string literal directly.  

Right now, we have this as our app source code: 

```html

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <script src='https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.js'></script>
</head>
<body>

    <div id="app">
      <user-list v-bind:users="allUsers"></user-list>
    </div>

    <script type="text/javascript">

      let userList = Vue.component('userList', {
      template : '<div>{{users}}</div>',
      props: ['users']
      
      });

       let app = new Vue({
           el : "#app",

           data(){
            return{
              allUsers : [
                {
                  name : 'John Doe',
                  about : 'Really nice guy'
                },
                {
                  name : 'Jane Dean',
                  about: 'Loves eggs'
                },
                {
                  name : 'Clark Kent',
                  about: 'Not your everyday reporter'
                }
              ]
            }
           }
          
       });

    </script>

</body>
</html>
```

Remember we said earlier that we want our component to be able to list all users passed to it. To do this, we need to perform List Rendering, using the `v-for` directive. The directive is used to render a list of items based on an array. 
The syntax is like this:

```html
<li v-for="item in items"></li> 
```

Here, items is an array and item is an alias for the current array item being iterated upon. Armed with the knowledge of list rendering, let’s extend our user-list component to iterate over all users. To do this, we replace our template with this: 

```javascript

template : `
        <ul>
          <li v-for="user in users">
            {{user.name}}
          </li>
        </ul>
`,

```

In case you are not familiar, the back-ticks are called template literals in modern JavaScript, they allow us to have multi-line statements, like the one above. You can learn more about template literals [here](https://dev.to/sarah_chima/an-introduction-to-es6-template-literals-94l)

What we have done above is to define a base `ul` element and then, iterate through, and dynamically create all the `<li>` tags in the element using the `v-for` list rendering directive.  If you run the code we currently have, this should be your output:

![Looping through the user object](https://res.cloudinary.com/ddbm6rq61/image/upload/v1528310219/3.png)


##Handling the Click Event

Because we want our components to be re-usable, we will not handle the click event inside the component, instead, we will return the event to the parent component, which will use passed in the payload to perform any action it pleases. The advantage of this is that we can use the same component for many different purposes. 

We will do this by making the `user-list` component emit an event when an item is clicked, and we will be handling this event on the parent component. 

Let’s add an onclick listener to the `<li>` element, we do this in Vue by adding the `@click` attribute. This click event will call an internal method, and pass the user’s `about` attribute to the method.


```html

<li v-for="user in users" @click="emitClicked(user.about)">
  {{user.name}}
</li>

```

You can see above, that there is a method passed to the click handler, called the emitClicked method, we will define this method by adding the methods attribute to our Vue component.

```javascript

methods : {
  emitClicked(data){
      this.$emit('item-clicked',data)
}
```




This method emits an event, with a payload, which the parent can listen for, and use for operations.


##Listening for Events

The easiest way to listen for an event in a parent component is by using the `v-on` attribute. Remember in the child component, we emitted an `item-clicked` event, so we can easily listen for the event by adding the `v-on:item-clicked` attribute to the `<user-list>` HTML tag.

```html
<user-list v-bind:users="allUsers" v-on:item-clicked="alertData"></user-list>
```

From the code above, we can see that there is a new method called `alertData`, This method is what handles the payload(data) passed out from the child component when it emitted the event. 

We will define the `alertData` method inside the main component by adding the methods attribute as well.

```javascript

 methods: 
{
  alertData(data)
  {
    alert(data)
  }
}
```
This method simply uses the native alert method to display the data that has been passed from the child component.  

Right Now our entire code should look like this:

```html

    <!DOCTYPE html>
    <html>
    <head>
        <title></title>
        <script src='https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.js'></script>
    </head>
    <body>
    
        <div id="app">
          <user-list v-bind:users="allUsers" v-on:item-clicked="alertData"></user-list>
        </div>
    
        <script type="text/javascript">
    
          let userList = Vue.component('userList', {
          template : `
            <ul>
              <li v-for="user in users" @click="emitClicked(user.about)">
                {{user.name}}
              </li>
            </ul>
          `,
    
          props: ['users'],
    
          methods : {
            emitClicked(data){
    
              this.$emit('item-clicked',data)
    
            }
          }
          
          });
    
           let app = new Vue({
               el : "#app",
    
               data(){
                return{
                  allUsers : [
                    {
                      name : 'John Doe',
                      about : 'Really nice guy'
                    },
                    {
                      name : 'Jane Dean',
                      about: 'Loves eggs'
                    },
                    {
                      name : 'Clark Kent',
                      about: 'Not your everyday reporter'
                    }
                  ]
                }
               },
    
               methods: 
               {
                  alertData(data)
                  {
                    alert(data)
                  }
               }
              
           });
    
        </script>
    
    </body>
    </html>
```

![Our Final Application](https://res.cloudinary.com/ddbm6rq61/image/upload/v1528310221/4.png)

The re-usability of this component lies in the fact that the `v-on:item-clicked` can accept different methods, and produce different outputs, hence, the `user-list`  component can be reused severally across the application.

###Conclusion
Components can be very useful in separating concerns for our front-end application and breaking it up into smaller logical bits. As a rule of thumb, components should perform a singular function, to enable maximum re-usability. In this article, we have been able to explore how to create a component, and pass data between the component and its parent.