Reputation: 3927
Can I react to an event in a vue template? Say a child component dispatches an event $dispatch('userAdded')
, could I do something like this in the parent component:
<div class="alert alert-info" v-if="userAdded">
User was created!
</div>
or, if not, can I access variables of the child component?
<div class="alert alert-info" v-if="$refs.addView.form.successful">
User was created!
</div>
I tried both without success.
Also, while I'm here, is there an expressive way to hide elements after a certain amount of time? Something like (to hide after 2s):
<div class="alert alert-info" v-if="$refs.addView.form.successful" hide-after="2000">
User was created!
</div>
Thanks!
edit: wrote my own hide-after
directive:
Vue.directive('hide-after', {
update: function(value) {
setTimeout(() => this.el.remove(), value);
}
});
<div class="alert alert-info" v-hide-after="2000">
This will be shown for 2 seconds
</div>
Upvotes: 2
Views: 11028
Reputation: 28992
The whole idea of events is that you can react to them. But you want the reaction to pass by the model. You really don't want unrelated bits of markup listening and reacting 'independently'. $dispatch is deprecated. To do this now, do the following...
In the child component, emit an event as follows
this.$emit('didIt' {wasItAwful:'yep',wereYouScared:'absolutely'});
In the parent, you register the event listener with v-on, as an attribute of the child's tag...
<adventure-seeking-child v-on:did-it='myChildDidIt' />
Then, in the parent's methods, define your handler.
methods : { myChildDidIt : function(payload){ ... } }
Docs are here.
Upvotes: 1
Reputation: 5986
Yes you can but you need to take this approach.
The code would look something like
parent
HTML
<div v-if="showAlert"></div>
Js
events: {
'alert.show': function () {
this.showAlert = true
},
'alert.hide': function () {
this.showAlert = false
}
},
data () {
return {
showAlert: false
}
}
Child
Js
methods: {
showAlert (show) {
show ? this.$dispatch('alert.show') : this.$dispatch('alert.hide')
}
}
The reason you should avoid using the $child and $parent is that it makes that component always depend on the fact that the parent will have the alert property and makes the child component lest modular
Since dispatch goes up until it hits a listener you can have several nested components in between the parent and child dispatching the alert control
UPDATE
Alternately, since you do not like the LOE of using events you can create a 2-way property on the child that either the parent or child can update
Example
Parent
HTML
<div v-if="showAlert"></div>
<child-component :show-alert.sync="showAlert"></child-component>
JS
data () {
return {
showAlert: false
}
}
Child
js
props: {
showAlert: {
type: Boolean,
twoWay: true
}
},
methods: {
showAlertInParent (show) {
this.$set('showAlert', show)
}
}
Upvotes: 4