Vue Tutorial 8 — Component Events
Join the DZone community and get the full member experience.
Join For FreeIn our pursuit of being able to handle large, scalable, maintainable web apps we became familiar with and learned about Vue Components. We learned how to:
- Define a component.
- Instantiate a component.
- Pass data to a component using props.
In this tutorial, we’ll learn how to trigger events in the app based on some user action registered by our “child” component.
Component Events
As we build out the blog feature, it may become necessary for our “child” components to communicate back to the “parent” app. For example, we may decide to include a feature to vote on comments. Let’s implement this now, and we’ll start by adding a button to the user-comment component from the previous tutorial
Vue.component('user-comment', {
props: ['comment'],
template: `<div class="my-5">
<p class="font-weight-bold">{{ comment.name }} said:</p>
<p>{{ comment.content }}</p>
<i class="far fa-thumbs-up"></i>
</div>`
})
The above component employs a template literal to allow our template to be more readable and span across multiple lines, rather than being written in a single line.
Our most immediate problem right now is the fact that nothing happens when the thumbs up icon is pressed. Let's fix this.
The parent app has the ability to listen to a particular event on a component:
xxxxxxxxxx
<user-comment
v-for="comment in comments"
v-bind:comment="comment"
v-bind:key="comment.id"
v-on:thumbs-up="thumbsUp"
>
</user-comment>
When the component triggers a thumbs-up event, we will then call the thumbsUp
method, which we must implement in the app:
xxxxxxxxxx
methods: {
thumbsUp: function () {
console.log("thumbsup pressed")
}
}
With the parent listening for a child’s thumbsUp
event, we must now trigger this event on icon click. To achieve this we will emit an event using the $emit
method
You may also like: How and Why We Moved to Vue.js.
xxxxxxxxxx
Vue.component('user-comment', {
props: ['comment'],
template: `<div class="my-5">
<p class="font-weight-bold">{{ comment.name }} said:</p>
<p>{{ comment.content }}</p>
<i class="far fa-thumbs-up" v-on:click="$emit('thumbs-up')"></i>
</div>`
})
As you can see, the thumbsUp
method gets triggered when the icons is pressed. We have successfully emitted an event from the child component to the parent. How about passing some data from the child to the parent? Let’s pass the comments id so the parent can know which comments should receive the new like.
xxxxxxxxxx
<i class="far fa-thumbs-up" v-on:click="$emit('thumbs-up', comment.id)"></i>
You can adjust the parents thumbsUp
method to show us what’s being passed from the child
xxxxxxxxxx
thumbsUp: function (event) {
console.log(`thumbsup pressed ${event}`)
}
Don't forget to pass this event, as per below code block
xxxxxxxxxx
<user-comment
v-for="comment in comments"
v-bind:comment="comment"
v-bind:key="comment.id"
v-on:thumbs-up="thumbsUp($event)"
>
</user-comment>
As you can see in the screenshot below, we now receive the id of the comment that was liked!
To update a comment's number of likes, we must naturally first add that property to our comments starting with a default value of 0
xxxxxxxxxx
comments: [
{id: 1, name: "Jerry", content: "I love Vue so much", likes: 0},
{id: 2, name: "Eric", content: "Vue.js solved all my relationship problems!", likes: 0},
{id: 3, name: "Sandra", content: "I'm currently on the beach coding Vue as we speak!", likes: 0},
]
Now, we can search the comments array by id and increment the number of likes
xxxxxxxxxx
methods: {
thumbsUp: function (commentId) {
console.log(`thumbsup pressed ${commentId}`)
let comment = this.comments.find(x => x.id === commentId)
if (comment != undefined) {
comment.likes += 1;
} else {
console.log("Comment not found")
}
}
}
To ensure that our “Like” mechanism works, let’s display the number of likes next to the icon inside the child component
xxxxxxxxxx
{{ comment.likes }} <i class="far fa-thumbs-up" v-on:click="$emit('thumbs-up', comment.id)"></i>
If you followed the tutorial correctly, you now have a working comment-like mechanism that looks like the following
Conclusion
In this tutorial, you’ve learned how to handle component events and how to literally “emit” them to the parent. This is a feature that I think you'll use quite often. As a challenge, I would suggest that you also implement a dislike button that decrements the number of likes for each comment following the methods you’ve learned today.
The code for this tutorial is available here.
Note: You can find parts one, two, three, four, five, six and seven of this series at their respective links.
Further Reading
Opinions expressed by DZone contributors are their own.
Trending
-
How To Design Reliable IIoT Architecture
-
Building and Deploying Microservices With Spring Boot and Docker
-
What Is Test Pyramid: Getting Started With Test Automation Pyramid
-
Build a Simple Chat Server With gRPC in .Net Core
Comments