Creating a component
It is known that even with the simplest applications, it is not good to keep the entire code in one file, but it is better to break it into several units, because that way the application is simplified and allows better visibility and easier debugging. Components are a great way to break the complexity of an application into smaller parts. In addition, components allow us to encapsulate our code, as well as to be able to use it more than once in the application (reusable code).
Essentially, a component represents an options object of a Vue instance. If ES6 syntax and module usage is available to us, then it is good to separate that options object into a separate file. That file within the Vue.js framework has a special extension .vue, and the name according to convention must begin with a capital letter and consists of three sections: template, script, style.
Example: ButtonCounter.vue
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
<template> <div> <button v-on:click="count++">Klikni me</button> <p>kliknuto {{ count }} puta </p> </div> </template> <script> export default { data() { return { count: 0 }; } }; </script> <style> button { font-size: 1rem; background-color: red; color: white; padding: 0.3rem 0.8rem; } </style> |
The advantages of using components are as follows:
- Syntax highlighting
- Component-scoped CSS
- A clearer application due to modular programming
NOTE:
For Vue version 2.0 template section must have only one root element, otherwise Vue.js throws an error.
|
1 2 3 4 |
<template> <button v-on:click="count++">Klikni me</button> <p>kliknuto {{ count }} puta </p> </template> |
The previous example throws an error, because there are two root elements in the template. The solution is to put both elements in a common wrapper element:
|
1 2 3 4 5 6 |
<template> <div> <button v-on:click="count++">Klikni me</button> <p>kliknuto {{ count }} puta </p> </div> </template> |
Component registration
In order to be able to implement the created component in our application (or in another component), it is necessary to register it (it must have a constructor function on the basis of which it is generated).
a) Global component registration
Globally registering the component allows us to use the component from different Vue instances or other components. We register the component using the component() method. This method accepts two arguments: tagname and options object:
|
1 2 3 4 5 |
const app = Vue.createApp({}) app.component('component_name', {/* options object*/}) app.mount('#app') |
Example
See the Pen
Untitled by Web Programming (@chos)
on CodePen.
|
1 |
Vue.component('name-tag', { /* options object*/ } |
Example
|
1 2 3 4 5 6 7 8 |
Vue.component('button-counter', { data: function () { return { count: 0 } }, template: '<button v-on:click="count++">Stisnuli ste dugme {{ count }} puta.</button>' }) |
b) Local registration of the component
Unlike the global registration of a component, when the components are available to all other components, with a locally registered component, the content of one component is not immediately available within another component, it is necessary to additionally import and locally register the component.
Local registration does not use the component() method, but the components property. That property is an object through which all local components are defined in the form of key/value pairs. The name of the component is defined through key, and value points to a variable representing the options object:
|
1 2 3 4 5 6 |
new Vue({ el:"#app", components: { 'button-counter' : { /* options object*/ } } }) |
or to extract the options object (important for “Single File Component”)
|
1 2 3 4 5 6 7 8 |
var button-counter-options = { /* options object*/ } new Vue({ el:"#app", components: { 'button-counter' : button-counter-options } }) |
“data” property in Vue component
The “data” property on components cannot be a regular object, because Vue.js is designed to throw an error in that case. The reason Vue.js prevents such a syntax (which is otherwise regular for within a Vue instance), is that an object defined in such a way would be shared across all created instances! To avoid this, we need to declare data as a function that returns an object with data properties, after which each instance of the component will get its own new copy of the initial “data” object.
|
1 2 3 4 5 |
data: function (){ return { message: "Hello" } } |
or if we are able to use ES6, we can write more simply:
|
1 2 3 4 5 |
data() { return { message: "Hello" }; } |
Example
See the Pen Components by Web Programming (@chos) on CodePen.
NOTE:
If we still wanted to share the same data object across multiple instances, there is a way to “capture” Vue.js. We need to extract the data object from the vue instance and assign it to a variable, then point the data property to that variable:
See the Pen Components and Common Data Object by Web programming (@chos) on CodePen.
If we were to return the data object to the instance, each component would then have its own data object, afterof which the counters would be separated.
|
1 2 3 |
components: { 'component-name' : { /* options object*/ } } |
Example
See the Pen
Local Components by Web Programming (@chos)
on CodePen.
NOTE:
When the single file component is used, it is in a separate file before registration, it is necessary to import it first (see example):
|
1 |
import ButtonCounter from './ButtonCounter.vue' |
Implementation of the component in HTML
<template> tag
A Vue application can insert a new element into the HTML. The place of adding a new HTML element is marked with the insertion of <template></template> Tag:
|
1 2 3 |
<div id="app"> <template></template> </div> |
This element does not exist until a Vue instance is created. What the template tag will be replaced with when creating a Vue instance is defined in the “template” property of the instance:
|
1 2 3 |
let app = Vue.createApp({ template: `<p>{{msg}}</p>` }) |
Example
See the Pen
Vue template by Web programming (@chos)
on CodePen.
<Component> tag
Components are implemented similarly to <template> tag, it is enough to embed a custom tag with the name of the component and it will “bring” its HTML elements, all logic, and styling defined in the component.
|
1 2 3 |
<div id="app"> <naziv-komponente></naziv-komponente> </div> |
Multiple instances of the same component can be used in the application, for that it is enough to insert the tag with the name of the component in several places within the HTML itself.

