When I have a form with veevalidate and submit it, the data is emitted to the parent component, but I struggle with resetting the form. According to the veevalidate guidelines, the form should be reset using $refs
.
- To set up the refs, follow this link:
- To reset the form, refer to:
My TypeScript app follows the guidelines, and the component structure looks like this:
<template>
<div>
<ValidationObserver v-slot="{ handleSubmit }" ref="form">
<form :model="form" @submit.prevent="handleSubmit(onSubmit)" novalidate>
<a-input-with-validation
:placeholder="placeholder"
:label="placeholder"
auto-complete="off"
name="comment"
type="text"
v-model="form.comment"
rules="required"
/>
<a-button-submit :translation-key="$t('dict.save')"/>
</form>
</ValidationObserver>
</div>
</template>
<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator'
import { ValidationObserver, ValidationProvider } from 'vee-validate'
import { OItemCommentFormChildOutput } from '@/components/organisms/forms/OItemCommentFormInterfaces'
import AInputWithValidation from '@/components/atoms/inputs/AInputWithValidation.vue'
import AButtonSubmit from '@/components/atoms/buttons/AButtonSubmit.vue'
@Component({
components: {
AButtonSubmit,
AInputWithValidation,
ValidationObserver,
ValidationProvider
}
})
export default class OItemCommentForm extends Vue {
@Prop()
comment?: string
@Prop({ default: true })
add!: boolean
$refs!: {
form: InstanceType<typeof ValidationObserver>;
}
placeholder!: string
form: OItemCommentFormChildOutput = {
comment: ''
}
mounted () {
this.$refs.form;
}
created () {
this.placeholder = String(this.add ? this.$t('dict.addComment') : this.$t('dict.editComment'))
this.form.comment = this.comment || ''
}
onSubmit () {
this.$emit('child-output', this.form as OItemCommentFormChildOutput)
// this.form.comment = ''
this.$refs.form.reset()
}
}
</script>
The a-input-with-validation
component code (from veevalidate):
<template>
<ValidationProvider
:vid="vid"
:name="nameAlt || name"
:rules="rules"
v-slot="{ errors, valid }"
>
<b-field
:label="label"
:prop="name"
v-bind="$attrs"
:auto-complete="autoComplete"
:type="{ 'is-danger': errors[0], 'is-success': valid }"
:message="errors"
>
<b-input
:name="name"
:type="type"
v-bind="$attrs"
:placeholder="placeholder"
v-model="innerValue"
:password-reveal="type === 'password'"
novalidate
/>
</b-field>
</ValidationProvider>
</template>
<style scoped>
.AInputWithValidation {}
</style>
<script lang="ts">
import { Component, Prop, Vue, Watch } from 'vue-property-decorator'
import { ValidationObserver, ValidationProvider } from 'vee-validate'
@Component({
components: {
ValidationObserver,
ValidationProvider
}
})
export default class AInputWithValidation extends Vue {
@Prop({ required: true })
value!: any
@Prop({ required: true })
label!: string
@Prop({ required: true })
name!: string
@Prop({ default: 'off' })
autoComplete!: string
@Prop({ default: 'text' })
type!: string
@Prop()
nameAlt?: string
@Prop()
placeholder?: string
@Prop()
vid?: string
@Prop()
rules?: string
innerValue = ''
created () {
if (this.value) {
this.innerValue = this.value
}
}
@Watch('innerValue')
innerValueHandle (newVal) {
this.$emit('child-output', newVal)
this.$emit('input', newVal)
}
@Watch('value')
valueValueHandle (newVal) {
this.innerValue = newVal
}
}
</script>
The app compiles without errors but fails to reset the form after submission. How can I reset the form without triggering the validation errors?
(Even moving the ref="form"
to the form tag did not resolve the issue.)