Reputation: 14239
I'm new to vue.js and am trying to understand how $emit
can be used. In the following code, every input
element except for the last one works as expected.
My assumption in the last input
element is that calling $emit
with an event name would be the same as calling the function which has that event name, but it doesn't call that function. What is occurring with this $emit?
I've read through Binding Native Events to Components and that shows that it is to be used differently as I'm doing it. All this approach started from me watching a YouTube video (7 Secret Patterns...), specifically at this time https://youtu.be/7lpemgMhi0k?t=21m57s where you can see that usage on the slide.
Here is the code in JSFiddle https://jsfiddle.net/sbtmfweq/
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="test-app">
<input v-model="text1" placeholder="edit me" @keyup.enter="submit"> {{ text1 }}
<br><br>
<input :value="text2" @input="inputEvent" @keyup.enter="submit"> {{ text2 }}
<br><br>
<input :value="text2" @input="inputEvent($event)" @keyup.enter="submit"> {{ text2 }}
<br><br>
<input :value="text2" @input="$emit('inputEvent', $event.target.value)"> {{ text2 }} | {{reversedText2}}
</div>
<script>
new Vue({
el: '#test-app',
data: {
text1: 'text1',
text2: 'text2',
},
methods: {
log: console.log,
submit: function(event) {
console.log("submit -->", event, event.target.value, '<--')
},
inputEvent: function(event) {
console.log("input 2 -->", event.target.value, '<--')
this.text2 = event.target.value
},
},
watch: {
text1: {
handler: function(newValue, oldValue) {
console.log("input 1 -->", newValue, '<-->', oldValue, '<--')
}
}
},
computed: {
reversedText2: function () {
return this.text2.toUpperCase()
}
}
})
</script>
Upvotes: 1
Views: 6055
Reputation: 433
it's normal that $emit
doesn't work in your case.
In fact, $emit
is used for communication between parent and child components. Here, you are using $emit
but you haven't defined any parent component.
Here is the docs for the custom events.
Hope it helps!
Upvotes: 0
Reputation: 34306
$emit
works like this.
Say you have 2 components, <parent>
and <child>
, where <child>
is inside <parent>
's template.
When <child>
emits an event, it can be handled by the <parent>
component only (unless you register a listener via $on
, but that's unrelated to your scenario). In your code, the $emit
call is executed within the scope of the parent component (which is the root component instantiated with new Vue()
); that is, the parent component is the one that's emitting the event. The root component has no parent so the emit call is pointless.
My assumption in the last
input
element is that calling$emit
with an event name would be the same as calling the function which has that event name, but it doesn't call that function.
This isn't true; the name of the event has no relation to the method registered as a listener for that event in the parent.
Upvotes: 1
Reputation: 2384
It's just a simple issue. Whenever you are dispatching an event, you have to add listener to it. In $emit, the first param is actually the name of the event.
As written in docs for $emit.
vm.$emit( eventName, […args] )
In the below code, I have added an event listener, using $on. Also I have changed the arg for $emit.
<input :value="text2" @input="$emit('inputEvent', $event)"> {{ text2 }} | {{reversedText2}}
<script>
new Vue({
...
created(){
this.$on('inputEvent', this.inputEvent);
}
...
})
</script>
I hope it helps.
Upvotes: 3