veevalidate reset form typescript не сбрасывает форму - PullRequest
1 голос
/ 02 августа 2020

У меня есть форма с veevalidate. При отправке формы данные отправляются родителю, а затем мне нужно сбросить форму. Следуя инструкциям veevalidate, должна быть возможность сбросить форму с помощью $refs.

Мое приложение на TypeScript, и, следуя руководствам, мой компонент выглядит следующим образом:

<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>

Код компонента a-input-with-validation (от 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>

Приложение компилируется отлично, поэтому, похоже, нет ошибок TS. При отправке данные передаются правильно. Но когда я пытаюсь вызвать метод reset, ничего не происходит. Форма не сбрасывается, а входное значение остается прежним. Если я также принудительно вставлю комментарий в форме в пустую строку, это заставит валидатор отобразить ошибки.

Как я могу сбросить форму после отправки формы и очистить ее содержимое, не вызывая ошибок проверки?

(перемещение ref="form" в тег формы тоже ничего не делает: /)

1 Ответ

0 голосов
/ 03 августа 2020

ValidationObserver s reset() сбрасывает только состояние проверки, но не поля формы. Хотя документы включают демонстрацию сброса формы, которая вручную очищает поля , в качестве альтернативы вы можете вызвать HTMLFormElement.reset() в элементе <form>, чтобы сбросить поля до их начальных значений. К элементу <form> можно получить доступ из SubmitEvent s target :

export default class OItemCommentForm extends Vue {

  async onSubmit(e) {
    // Wait microtick for models to update before resetting validation state
    await this.$nextTick()
    this.$refs.form.reset()

    // Reset form in next macrotick
    setTimeout(() => e.target.reset())
  }
}

Ключ - сбросить форму в следующем макротике ( через setTimeout с нулевым таймаутом).

Изменить форму сброса после отправки

...