Vue Components
Components in Vue lets us decompose our web page into smaller pieces that are easy to work with.
We can work with a Vue component in isolation from the rest of the web page, with its own content and logic.
A web page often consists of many Vue components.
What are Components?
Components are reusable and self-contained pieces of code that encapsulates a specific part of the user interface, so that we can make Vue applications that are scalable and easier to maintain.
We can make components in Vue ourselves, or use built-in components that we will learn about later, like <Teleport>
or <KeepAlive>
. Here we will focus on components we make ourselves.
Creating a Component
Components in Vue is a very powerful tool because it lets our web page become more scalable and bigger projects become easier to handle.
Let's make a component and add it to our project.
Create a new folder
components
inside thesrc
folder.Inside the
components
folder, create a new fileFoodItem.vue
. It is common to name components with PascalCase naming convention, without spaces and where all new words starts with a capital letter, also the first word.Make sure the
FoodItem.vue
file look like this:
Code inside the FoodItem.vue
component:
<template>
<div>
<h2>{{ name }}</h2>
<p>{{ message }}</p>
</div>
</template>
<script>
export default {
data() {
return {
name: 'Apples',
message: 'I like apples'
}
}
};
</script>
<style></style>
As you can see in the example above, components also consist of <template>
, <script>
and <style>
tags, just like our main App.vue
file.
Adding The Component
Notice that the <script>
tag in the example above start with export default
. This means that the object containing the data properties can be received, or imported, in another file. We will use this to implement the FoodItem.vue
component into our existing project by importing it with the main.js
file.
First, rewrite the last line into two lines in your original main.js
file:
main.js
:
import { createApp } from 'vue'
import App from './App.vue'
const app = createApp(App)
app.mount('#app')
Now, add the FoodItem.vue
component by inserting lines 4 and 7 in your main.js
file:
main.js
:
import { createApp } from 'vue'
import App from './App.vue'
import FoodItem from './components/FoodItem.vue'
const app = createApp(App)
app.component('food-item', FoodItem)
app.mount('#app')
On line 7, the component is added so that we can use it as a custom tag <food-item/>
inside the <template>
tag in our App.vue
file like this:
App.vue
:
<template>
<h1>Food</h1>
<food-item/>
<food-item/>
<food-item/>
</template>
<script></script>
<style></style>
And, let's add some styling inside the <style>
tag in the App.vue
file. Make sure the development server is running, and check out the result.
Example
App.vue
:
<template>
<h1>Food</h1>
<food-item/>
<food-item/>
<food-item/>
</template>
<script></script>
<style>
#app > div {
border: dashed black 1px;
display: inline-block;
margin: 10px;
padding: 10px;
background-color: lightgreen;
}
</style>
Run Example »
Development mode: When working with your Vue projects, it is useful to always have your project in development mode by running the following code line in the terminal:
npm run dev
Individual Components
A very useful and powerful property when working with components in Vue is that we can make them behave individually, without having to mark elements with unique IDs like we must do with plain JavaScript. Vue automatically takes care to treat each component individually.
Let's make the <div>
elements count when we click them.
The only thing added to our main application file App.vue
is in CSS to have the cursor look like a hand pointing during hover to imply that there is some sort of click functionality.
CSS code added to the <style>
tag in App.vue
:
#app > div:hover {
cursor: pointer;
}
In our component file FoodItem.vue
we must add a data property count
, a click listener to the <div>
element, a method to run when click happens to increment the counter, and text interpolation {{}}
to show the count.
Example
FoodItem.vue
:
<template>
<div v-on:click="countClicks">
<h2>{{ name }}</h2>
<p>{{ message }}</p>
<p id="red">You have clicked me {{ clicks }} times.</p>
</div>
</template>
<script>
export default {
data() {
return {
name: 'Apples',
message: 'I like apples',
clicks: 0
}
},
methods: {
countClicks() {
this.clicks++;
}
}
}
</script>
<style>
#red {
font-weight: bold ;
color: rgb(144, 12, 12);
}
</style>
Run Example »
We don't have to define unique IDs or do any extra work for Vue to handle the counting individually for each <div>
element, Vue just does this automatically.
But except for the different counter values, the content of the <div>
elements is still the same. In the next page we will learn more about components so that we can use components in a way that makes more sense. For example it would make more sense to display different kind of food in each <div>
element.