Vue.js applications are all about creating components. Making them interact with each other is where the fun begins. Using props and events is the way how to do this in Vue.js. A common question around this topic is how to make your child-components react to events.
TL;DR. You don't.
You don't fire events to your child-components. Instead, you change the prop on a child-component and then use a watcher in that child-component to fire some logic.
Events fire up, props are passed down
Before we start with this example, you have to understand the following concept:
- When a component wants to let its parent know something has happened, it fires an event outside of itself
- When the parent wants to let the child know that something has changed, it modifies the prop that is passed to the child component'
So you don't pass events to a child-component, you change the prop of a child. And then in your child-component you create a watcher for that props. This is the way to make a child-component react on things happening outside of it.
The child component
This is a really simple button-component which can do 2 things. It can emit an event with the name 'icon-clicked' and it can alert whatever it gets through its buttonText-prop.
<template>
<div class="button">
{{ buttonText }}
<i @click="$emit('icon-clicked', $event.target.value)">?</i>
</div>
</template>
<script>
export default {
props: {
buttonText: {
type: String,
default: 'Submit',
}
},
watch: {
buttonText() {
this.alertMe();
}
},
methods: {
alertMe() {
window.alert(this.buttonText);
}
}
}
</script>
The child-component can do two things:
- Emit an event with the name
icon-clicked
- Show an alert with the content of the prop
buttonText
The watch property makes the alertMe
method fire when the buttonText
has changed.
The parent component
<template>
<div class="container">
<div class="help-text" v-if="showHelpText">Show some help text</div>
<btn-component @icon-clicked="toggleHelpText" :button-text="buttonText"/>
</div>
</template>
<script>
import BtnComponent from '~/components/BtnComponent'
export default {
components: {
BtnComponent
},
data() {
return {
showHelpText: false,
buttonText: 'Help me',
}
},
methods: {
toggleHelpText() {
this.showHelpText = !this.showHelpText
this.buttonText = this.showHelpText ? 'Close me' : 'Help me';
}
}
}
</script>
When the btn-component has fired the event icon-clicked
, the toggleHelpText
method is being executed. This method sets two variables:
- The
buttonText
is set to 'Close me' or 'Help me' - The
showHelpText
toggles the help-text block
That's it
This is the way you interact between components. You can use this concept in many ways.
Here are some more examples on using events in Vue.