VueJS part 6: Components introduction

VueJS part 6: Components introduction

·

5 min read

Introduction

Recently, I started learning VueJS, and this article is part of the series of my notes while learning it. Components are a very important part of Vue, and in this article, I am giving a brief introduction to what they are and how to use them.

What are components

In all of the posts so far, I just created the Vue application and mounted it to the specific element. However doing that would cause HTML to grow huge, and the application object would be overly populated with all the data and methods. Soon, it would become impossible to update it. So there is a need to exclude pieces of logic and structure into reusable sections. This is what components are. A reusable structure that can contain their structure with HTML, style with CSS, and logic with JavaScript. These are used as new custom HTML tags.

Creating the first component

For this introductory post, I am using a Vue loaded from CDN. Also, when creating the first component, there is one important thing I need to note. I am using the Vue version 3. This is important to note because in version 3, defining components slightly changed. In older versions, it was done on the global Vue object. Since version 3, you need to create a new Vue application, and then register components on that application.

const app = Vue.createApp({
  data() {
    return { }
  },
  methods: {
  }
})

As a first component, I will just make it a simple one, containing the hardcoded first and last name of the person. But before registering the component, we should create a configuration object for our directive. This object is quite similar to the initialization object of the app.

const PersonDetails = {
  template: `
    <div>
      <div>John, Doe</div>
    </div>`,
  data() {
    return { }
  },
  methods: { }
}

This would be among the simplest versions of this object. We have the methods object that would contain all our logic, which is empty above. Data function that returns data we might want to expose. And last is the template string. In future posts, I will cover better options to do those, but one way is to add a template property to the initialization object and add your template to it as a string.

Now that object is created, the component can be registered. That is done by calling the component function on the created Vue application.

app.component('PersonDetails', PersonDetails)

In the example above, I passed two parameters, the first one being the name of the component and the second being the component configuration object. For the name I chose to call it the PersonDetails, however, as an alternative to the same name I could have also called it person-details. This second version is the name of the tag I will use in the template. So to simplify it, components are named all lowercase, with dashes between words, but when registering them, dashes can be omitted with each word being capitalized.

<div id="app">
    <person-details></person-details>
</div>

As you can see above, using a component once it is registered, is just like using any other HTML element. Just a matter of using a tag with a component name. This will result in the template being rendered in its place.

Passing data to the component

Above, I just used hardcoded data to display the first and last names in the component. But that is not very reusable. And often you would want to pass some values to it. While that is something I will cover in more detail in some of the future posts, as component communication is a bigger topic. Still, I do want to touch a bit on the passing data.

Passing data is quite similar to the regular HTML elements. You just add attributes when using components. The difference with vue is that you should use vue bind to pass the value, and in the string, the value is a JavaScript expression.

<person-details :first-name="'John'" :last-name="'Doe'" />

The code above is an example of how that would look like. You can see I used a colon before the attribute name. That is a shorthand for the v-bind directive. The second thing to note is that I used single quotes inside of the double ones. That is because inside of the string is a JavaScript expression, so if you want to pass the hardcoded string value, then it needs to be wrapped into another quote. Otherwise, it will try to pass non non-existent variable called John.

Now that values are passed, we need to somehow consume them inside of the component. But for that, we need to first adjust the component to know it should expect such value. That is done by adding another property to the component configuration object. This property is called props, and its value is an array containing camel-cased names of attributes we are passing.

const PersonDetails = {
  template: `
    <div>
      <div>John, Doe</div>
    </div>`,
  data() {
    return {  }
  },
  props: ["firstName", "lastName"],
  methods: { }
}

This was just defining that we will pass those values, we are still not using them. To access them, you can use the this.$props value. There are multiple ways to expose it to the template, for simplicity this time, I will just use it in the data object and make it accessible with the same names as they are passed to the component.

const PersonDetails = {
  template: `
    <div>
      <div>{{firstName}}, {{lastName}}</div>
    </div>`,
  data() {
    return {
      firstName: this.$props.firstName,
      lastName: this.$props.lastName
    }
  },
  props: ["firstName", "lastName"],
  methods: { }
}

Apps vs Components

You might look at this and think, when would you want to use components and when apps. Apps can't communicate with each other, while there are ways for components. So if you are expecting code to work together, you probably want to create reusable components.


The code used in this article can be found in my GitHub repository.


For more, you can follow me on Twitter, LinkedIn, GitHub, or Instagram.