Oduah Chigozie Technical writer | Frontend developer | Blockchain developer

A definitive guide to Vue 3 components

5 min read 1652

A Definitive Guide To Vue 3 Components

Components in Vue web applications are very important because they can be used in very simple ways to make very complex applications. In this article, we’ll cover the basics of Vue 3 components and how to use them.

What are components in Vue 3?

Components are reusable pieces of UI code that build functional web applications. They can be used as building blocks or they can be used to prevent rewriting of the same pieces of code over and over again.

Vue applications usually consist of a root component and any number of other components. Also, all components have a component object that holds the data, the component’s logic, and a template script that shows what the component will display.

Creating a component in Vue 3

Before we start creating components, we must first create a basic Vue application. To do that, create an index.html file inside a project directory of your choice. Then, open it in an IDE and write the following into it:

<html>
    <head>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/3.2.26/vue.global.min.js"></script>
    </head>
    <body>
        <div id="app">
        </div>

        <script>
            const app = Vue.createApp({});
            app.mount("#app");
        </script>
    </body>
</html>

In the above code, we add the Vue 3 library to the HTML code with the script tag on the third line, creating the Vue app in the script tag with the const app = Vue.createApp({}); and mounted using app.mount("#app");.

Root components in Vue 3

All Vue web applications have a root component. This component binds to the app view (in the above code, it is the div element with an app ID).

To create a root component, we start with an empty object and call it RootComponent by convention. This object is then passed to the Vue.createApp() function:

...
<script>
    const RootComponent = {};
    const app = Vue.createApp(RootComponent);
    app.mount("#app");
</script>
...

This will be the start of our web application. In our root component, we can bind some variables to it to create a sort of state in our component.

To add binding variables to the component, let’s start by creating a data method in the component object. This method will return an object that contains the data the component will use:

...
<script>
    const RootComponent = {
        data: function () {
            return {
                greeting: "Hello",
            }
        }
    };
    ...
</script>
...

In this example, the greeting variable is now bound to the root component, and we can now use the binding like so:

We made a custom demo for .
No really. Click here to check it out.

...
<div id="app">
    {{ greeting }}
</div>

<script>
...

This will display the text hello on the view. We can also add more binding variables to the component by adding it to the data method’s return value. And then, we can use more than one binding in the component:

...
<div id="app">
    {{ greeting }}, {{ name }}
</div>

<script>
    const RootComponent = {
        data: function () {
            return {
                greeting: "Hello",
                name: "John",
            }
        }
    };
    ...
</script>
...

Creating a simple component

To create a component in Vue, we start with an empty object, just like the root component. But, instead of passing it to the Vue.createApp() function, the same way it was done in the root component, we register it to the component that we want to use it in.

We will also need a template that the component displays when used.

The way components are registered in Vue is by creating a components member in a component object that holds a JavaScript object of key-value pairs with the component’s name as the key and the component object as the value.

As an extension to the last piece of code, let’s create and register a custom-button component:

...
<script>
    const CustomButton = {};
    const RootComponent = {
        data: function () {
            return {
                greeting: "Hello",
                name: "John",
            }
        },
        components: {
            'custom-button': CustomButton,
        },
    };
    const app = Vue.createApp(RootComponent);
    app.mount("#app");
</script>
...

Before we begin to use the component, we must add the template, which is usually written in a script tag with the type attribute as vue-template to prevent the browser from executing it and throwing an error to the console.

It also has an ID that the component object uses to find the template. So, let’s start by creating a template tag with the custom-button ID and placing a Click Me! button in it:

...
</div>

<script type="vue-template" id="custom-button">
    <button>Click Me!</button>
</script>

<script>
...

Then, we can bind it to the component:

...
<script>
    const CustomButton = {
        template: "#custom-button"
    };
...
</script>
...

Here, the template member of the component object uses CSS selectors to find the template tag. The # at the beginning of the string signifies that any word that follows it is an ID to an element in the DOM.

We can now use the custom-button component in the root component in the following way:

...
<div id="app">
    {{ greeting }}, {{ name }}
    <custom-button></custom-button>
</div>

<script type="vue-template" id="custom-button">
...

In Vue, all components must have a start tag and an end tag, which means you cannot use a self-closing tag like <custom-button />; it must be written like the following:

<custom-button></custom-button>

Adding state to Vue 3 components

Adding state to Vue components can be done the same way as the root component by using a data method in the component object. In the following example, we will add a buttonText state that contains the text inside button element of the custom-button component:

...
<script>
    const CustomButton = {
        template: "#custom-button",
        data: function () {
            return {
                'buttonText': "Click me!"
            }
        }
    }
    ...
</script>
...

And then we use it inside the template script’s button tag, like so:

...
</div>

<script type="vue-template" id="custom-button">
    <button>{{ buttonText }}</button>
</script>

<script>
...

Handling props in Vue 3

Props in Vue are attributes that are passed to components, just like HTML elements. They promote the flexibility and reusability of components, which makes it possible to use the same piece of code for slightly different scenarios, making the UI more efficient.

To pass a prop to a component, we pass it in the same way we pass HTML attributes:

 <component prop="value"></component>

We can then update the custom-button component by adding the text prop that holds the content of the component’s button:

...
<div id="app">
    {{ greeting }}, {{ name }}
    <custom-button text="Click me!"></custom-button>
</div>

<script type="vue-template" id="custom-button">
...

After that, we go to the component’s object (CustomButton) and add the props value to it. The props value holds an array of the props that will pass to the component.

That means if we have one prop in the component, it will look something like this:

 props: ['prop1']

Then, if we have other props, they will be added to the props value like this:

props: ['prop1', 'prop2']

Now, we update the CustomButton component:

...
<script>
    const CustomButton = {
        template: "#custom-button",
        data: function () {
            return {
                'buttonText': "Click me!"
            }
        },
        props: ['text']
    }
    ...
</script>
...

And then we can use the text prop value in the template:

...
</div>

<script type="vue-template" id="custom-button">
    <button>{{ text }}</button>
</script>

<script>
...

Since we won’t use the buttonText binding variable again, we can remove it from the component object:

...
<script>
    const CustomButton = {
        template: "#custom-button",
        props: ['text'],
    }
    ...
</script>
...

Nesting components in Vue 3

It is also possible to nest components inside other components in Vue, which leads to a concept called composition.

Composition involves using smaller components to build larger ones. This helps make the UI more efficient and easy to maintain because large and complex components are composed of smaller, easy-to-handle components.

In the following example, let’s build a start and stop button using the CustomButton component.

Let’s first create a new component object called StartStopButton:

<script>
    const CustomButton = {...
    };

    const StartStopButton = {

    }

    const RootComponent = {
    ...
</script>
...

Note that the ... in the second line of the code fragment above means that the block was dropped.

Then, create a template script and link it to the object:

...
<script type='vue-template' id="start-stop-button">

</script>

<script>
    const CustomButton = {...
    };

    const StartStopButton = {
        template: '#start-stop-button',
    }

    const RootComponent = {
    ...
</script>
...

After linking, register CustomButton in the StartStopButton component by creating an object member in the component named components. This component will hold an object of key-value pairs that have the component’s name as the key and the component’s object as the value:

...
<script>
    const CustomButton = {...
    };

    const StartStopButton = {
        template: '#start-stop-button',
        components: {
            'custom-button': CustomButton,
        }
    }
...
</script>
...

And then, we can use it in the template script like so:

...
<script type="vue-template" id="custom-button">...
</script>

<script type='vue-template' id="start-stop-button">
    <custom-button text='start'></custom-button>
    <custom-button text='stop'></custom-button>
</script>

<script>
...

Finally, in the root component, we can change the registered component from 'custom-button': CustomButton, to 'start-stop-button': StartStopButton and change the app view to the following:

...
<div id="app">
    {{ greeting }}, {{ name }}
    <start-stop-button></start-stop-button>
</div>
...
<script>
    ...
    const RootComponent = {
        data: function () {
            return {
                greeting: "Hello",
                name: "John",
            }
        },
        components: {
            'start-stop-button': StartStopButton
        },
    };
    ...
</script>
...

Conclusion

I hope this article helped you understand the process of creating components in Vue 3 and using them to build complex applications. But, if you still do not find any of the sections clear or could not follow along, let me know in the comments.

A demo of the code can be seen via CodePen. Thank you for reading and have a nice day!

Experience your Vue apps exactly how a user does

Debugging Vue.js applications can be difficult, especially when there are dozens, if not hundreds of mutations during a user session. If you’re interested in monitoring and tracking Vue mutations for all of your users in production, try LogRocket. https://logrocket.com/signup/

LogRocket is like a DVR for web and mobile apps, recording literally everything that happens in your Vue apps including network requests, JavaScript errors, performance problems, and much more. Instead of guessing why problems happen, you can aggregate and report on what state your application was in when an issue occurred.

The LogRocket Vuex plugin logs Vuex mutations to the LogRocket console, giving you context around what led to an error, and what state the application was in when an issue occurred.

Modernize how you debug your Vue apps - .

Oduah Chigozie Technical writer | Frontend developer | Blockchain developer

2 Replies to “A definitive guide to Vue 3 components”

Leave a Reply