I'm using the latest version of Vue 3, with no other vendors.
It may be a bug, or it is an expected behaviour, but I lost a couple of hours finding why my form component was firing the submit event twice.
It fact, if you listen to @submit on your form, and then $emit('submit') so you can listen to this event on the parent component, the event will be fired twice.
More than words, here is a pen to show this: https://codepen.io/rekam/pen/dyeqxyy
const { createApp } = Vue
const TestForm = {
template: `
<form @submit.prevent.stop="onSubmit">
<input type="text" />
<input type="submit" value="in component" />
</form>
`,
props: {
eventName: { type: String }
},
methods: {
onSubmit() {
this.$emit(this.eventName)
}
}
}
createApp({
template: `
<div>
<TestForm event-name="submit" @submit="() => onSubmit('with event name [submit]')" />
<TestForm event-name="other" @other="() => onSubmit('with event name [other]')" />
<blockquote>
<p v-for="(log, i) in logs" :key="i">{{ log }}</p>
</blockquote>
<input type="button" value="clear" @click="logs = []" />
</div>
`,
components: { TestForm },
data: () => ({
logs: []
}),
methods: {
onSubmit(msg) {
console.log(msg)
this.logs.push(msg)
}
}
}).mount('#app')
I can live with that, I just need to give a specific name to my own submit event. My question is: why is this happening and is it expected?
EDIT
I just found that wrapping the form tag in a div get rid of the second submit event. To have the submit event fired twice, you need:
- your form beign the top level dom element in your component
- emit an event named "submit"
CodePudding user response:
you call submit twice with an eventlistener you created from emit and another from @submit you added to your form tag. you should use one of them to submit your form.
CodePudding user response:
You dont need to add the event @submit.prevent.stop="onSubmit" in you're child component because it will be inherited from the parent component';
template: `
<form>
<input type="text" />
<input type="submit" value="in component" />
</form>
`,
template: `
<div>
<TestForm event-name="submit" @submit.prevent="() => onSubmit('with event name [submit]')" />
<TestForm event-name="other" @submit.prevent="() => onSubmit('with event name [other]')" />
<blockquote>
<p v-for="(log, i) in logs" :key="i">{{ log }}</p>
</blockquote>
<input type="button" value="clear" @click="logs = []" />
</div>
`,