Vue 3 is the up and coming version of Vue front end framework.
It builds on the popularity and ease of use of Vue 2.
In this article, we’ll look at how to create simple Vue 3 components.
Components
Components are reusable Vue instances with a name.
For instance, we can create a component by writing:
<!DOCTYPE html>
<html lang="en">
<head>
<title>App</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="app">
<button-counter ></button-counter>
</div>
<script>
const app = Vue.createApp({});
app.component("button-counter", {
data() {
return {
count: 0
};
},
template: `
<div>
<button @click="count--">
decrement
</button>
<p>{{ count }}</p>
</div>
`
});
app.mount("#app");
</script>
</body>
</html>
We create a component with a button and a p element.
When we click the button, the count
is decrement, and the value is displayed in the p element.
Then we used the button-counter
element in the app’s template.
We can reuse the component multiple times.
For instance, we can write:
<!DOCTYPE html>
<html lang="en">
<head>
<title>App</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="app">
<button-counter></button-counter>
<button-counter></button-counter>
<button-counter></button-counter>
</div>
<script>
const app = Vue.createApp({});
app.component("button-counter", {
data() {
return {
count: 0
};
},
template: `
<div>
<button @click="count--">
decrement
</button>
<p>{{ count }}</p>
</div>
`
});
app.mount("#app");
</script>
</body>
</html>
Now we have 3 instances of the button-counter
component.
They all have their own template and state.
Organizing Components
We got to organize our components well since we’ll probably have many of them in an app.
We can put them in a tree.
So we divide our app into small components we nest components to build what we want.
Passing Data to Child Components with Props
Our previous example didn’t have any way to get data from a parent component.
However, Vue 3 provides us with a way to pass data from parent to child with props.
Props are custom attributes that we can register on a component.
When a value is passed into the prop attribute, it becomes a property of the component instance.
For instance, we can create a component that takes props and use it by writing:
<!DOCTYPE html>
<html lang="en">
<head>
<title>App</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="app">
<blog-post title="hello world"></blog-post>
</div>
<script>
const app = Vue.createApp({});
app.component("blog-post", {
props: ["title"],
template: `<h1>{{ title }}</h1>`
});
app.mount("#app");
</script>
</body>
</html>
We create the blog-post
component with the title
prop so that we can display it on the template.
The props
property has an array of strings of the prop names.
Having that means we registered that props to be allowed to be passed into our component.
A component can have as many props as we want.
If we have an array of data, we can use the v-for
directive to render them.
For example, we can write:
<!DOCTYPE html>
<html lang="en">
<head>
<title>App</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="app">
<todo-item v-for="t of todos" :todo="t" :key="t.id"></todo-item>
</div>
<script>
const app = Vue.createApp({
data() {
return {
todos: [
{ id: 1, name: "eat" },
{ id: 2, name: "drink" },
{ id: 3, name: "sleep" }
]
};
}
});
app.component("todo-item", {
props: ["todo"],
template: `<p>{{ todo.name }}</p>`
});
app.mount("#app");
</script>
</body>
</html>
to render an array with components.
We have the todo-item
component with the todo
prop registered.
The template
property rendered the name
property of the array.
todo-item
is used with v-for
to render the todo items.
We pass in the todo value with the todo
prop with :todo='t'
and do the same with the key
prop.
The key
prop is used to let Vue identify each element uniquely.
Conclusion
We can create our own components with the app.component
method so that we can divide our Vue app into manageable pieces.