Vueponent('rating-edit', {
template:`
<form>
<input v-model="rating.title" type="text">
<textarea v-model="rating.remark">{{rating.remark}}</textarea>
<button type="button"
@click="submit">
Save
</button>
</form>`,
props:['rating'],
methods: {
submit: function submit () {
let rating = this.rating;
this.$emit('submit', rating);
console.log('submit was emitted');
}
}
});
const aRating = {
title: 'title',
remark: 'remark'
};
let vueApp = new Vue({
el: '#rating-edit-container',
data: {
rating: aRating
}
});
vueApp.$on('submit', function(rating) {
console.log('vue on submit', rating);
});
<script src=".min.js"></script>
<div id="rating-edit-container">
<rating-edit :rating="rating"></rating-edit>
</div>
Vue.ponent('rating-edit', {
template:`
<form>
<input v-model="rating.title" type="text">
<textarea v-model="rating.remark">{{rating.remark}}</textarea>
<button type="button"
@click="submit">
Save
</button>
</form>`,
props:['rating'],
methods: {
submit: function submit () {
let rating = this.rating;
this.$emit('submit', rating);
console.log('submit was emitted');
}
}
});
const aRating = {
title: 'title',
remark: 'remark'
};
let vueApp = new Vue({
el: '#rating-edit-container',
data: {
rating: aRating
}
});
vueApp.$on('submit', function(rating) {
console.log('vue on submit', rating);
});
<script src="https://vuejs/js/vue.min.js"></script>
<div id="rating-edit-container">
<rating-edit :rating="rating"></rating-edit>
</div>
In a legacy frontend code I'd like implement a vue based ponentized form and have it return the data on submit.
This is the ponent code. Please note the submit function firing this.$emit('submit', rating);
let result = {
props:['rating'],
methods: {
submit: function submit () {
let rating = this.rating;
this.$emit('submit', rating);
console.log('submit fired');
}
}
};
export default result;
And now in the legacy code, I am waiting for the events:
import Vue from 'vue';
import ratingEditVue from './rating-edit.vue';
Vue.ponent('rating-edit', ratingEditVue);
const aRating = {
title: 'title',
remark: 'remark'
};
let vueApp = new Vue({
el: '#rating-edit-container',
data: {
rating: aRating
}
});
vueApp.$on('submit', function(rating) {
console.log('vue on submit', rating);
});
As far as I understand the Vue events this should work. But $on('submit', handlerFunction) just never gets called.
Addendum:
I've fiddled the example. I apologize for not having done this in the first place.
Share Improve this question edited Jul 18, 2017 at 13:06 LongHike asked Jul 18, 2017 at 11:53 LongHikeLongHike 4,4608 gold badges50 silver badges86 bronze badges 2- Can you provide any plete fiddle for your case? – donMateo Commented Jul 18, 2017 at 12:04
-
2
You are
$emit
ing in a child ponent and setting up$on
to catch events in the parent.$on
catches events emitted in the current Vue (think of an event bus), so have the parent set it up on the child. – Roy J Commented Jul 18, 2017 at 12:58
2 Answers
Reset to default 11The issue is that you are emitting along the same scope depth of your rating-edit
ponent.
If you instead emit to the parent with this.$parent.$emit
, the event will be received by the parent. Note, if you need to do this in multiple places or at multiple depths, you want to use an event bus instead.
Vue.ponent('rating-edit', {
template:`
<form>
<input v-model="rating.title" type="text">
<textarea v-model="rating.remark">{{rating.remark}}</textarea>
<button type="button"
@click="submit">
Save
</button>
</form>`,
props:['rating'],
methods: {
submit: function submit () {
let rating = this.rating;
this.$parent.$emit('submit', rating);
console.log('submit was emitted');
}
}
});
const aRating = {
title: 'title',
remark: 'remark'
};
let vueApp = new Vue({
el: '#rating-edit-container',
data: {
rating: aRating
}
});
vueApp.$on('submit', function(rating) {
console.log('vue on submit', rating);
});
<script src="https://vuejs/js/vue.min.js"></script>
<div id="rating-edit-container">
<rating-edit :rating="rating"></rating-edit>
</div>
vueApp.$on('submit', function(rating) {
console.log('vue on submit', rating);
});
Your handler here will only be executed in response to submit
events emitted from vueApp
directly (i.e. vueApp.$emit('submit')
), which I don't think is happening in your code (which isn't fully provided).
Vue events do not bubble.
Suppose your #rating-edit-container
template is something like this:
<template id="rating-edit-container">
<div>
<rating-edit @submit="onRatingSubmit"></rating-edit>
</div>
</template>
Then you should have your handler (onRatingSubmit
) declared in the methods of your ponent like this:
let vueApp = new Vue({
el: '#rating-edit-container',
methods: {
onRatingSubmit(rating) {
console.log('rating submit', rating);
},
},
});
EDIT
You still have the same issue as what I described. I modified your snippet by removing the emission on $parent
instead of this
and registering the listener on the <rating-edit>
element in the template.
Vue.ponent('rating-edit', {
template:`
<form>
<input v-model="rating.title" type="text">
<textarea v-model="rating.remark">{{rating.remark}}</textarea>
<button type="button"
@click="submit">
Save
</button>
</form>`,
props:['rating'],
methods: {
submit: function submit () {
let rating = this.rating;
this.$emit('submit', rating);
console.log('submit was emitted');
}
}
});
const aRating = {
title: 'title',
remark: 'remark'
};
let vueApp = new Vue({
el: '#rating-edit-container',
data: {
rating: aRating
},
methods: {
onSubmit(rating) {
console.log('vue on submit', rating);
},
},
});
<script src="https://vuejs/js/vue.min.js"></script>
<div id="rating-edit-container">
<rating-edit :rating="rating" @submit="onSubmit"></rating-edit>
</div>