Форма $ ref не определена внутри метода? - PullRequest
1 голос
/ 28 мая 2020

У меня очень простая форма Vuetify с ref="form". Когда я нажимаю кнопку «Отправить», я хочу подтвердить и программно отправить форму, однако по какой-то причине this.$refs.form возвращает undefined.

undefined refs

Я почти надеясь, что это что-то глупое, вроде опечатки, потому что это так просто!

<template>
  <v-form
    v-if="!submitted"
    ref="form"
    v-model="valid"
    name="contactForm"
    data-netlify="true"
    data-netlify-honeypot="bot-field"
    method="POST"
    @submit.prevent="submit">
    <input
      type="hidden"
      name="form-name"
      value="contactForm">

    ...input fields

    <v-row justify="center">
      <v-col
        sm="12"
        class="text-center">
        <v-btn
          :disabled="!valid || sendingForm"
          color="accent"
          depressed
          :ripple="false"
          x-large
          type="submit">
          {{ sendingForm ? 'Loading...' : 'Submit' }}
        </v-btn>
      </v-col>
    </v-row>
    <p class="d-none">
      <label for="bot-field">Don't fill this out: </label>
      <input
        type="text"
        name="bot-field">
    </p>
  </v-form>
</template>

<script>
  export default {
    methods: {
      async submit() {
        this.sendingForm = true;
        console.log('refs: ', this.$refs); <-- returns undefined for this.$refs.form
        if (this.$refs.form.validate()) {
          console.log('refs: ', this.$refs); <-- also returns undefined for this.$refs.form
          this.$refs.form.submit();
          this.submitted = true;
        }
        this.sendingForm = false;
      }
    },
  }
</script>

Я попытался удалить v-if в форме, удалив type="submit / добавив @click="submit на кнопке, удалив @submit.prevent="submit из формы ... вроде ничего не работает! Кто-нибудь сталкивался с чем-то подобным? Спасибо!

Ответы [ 2 ]

1 голос
/ 31 мая 2020

Вот что у меня сработало

<v-form
  ref="form"
  v-model="valid"
  name="contactform1"
  action="/contact"
  method="post"
  data-netlify="true"
  netlify-honeypot="bot-field"
>
  <input type="hidden" name="form-name" value="contactform1" />
  <v-row class="spacing6">
    <v-col cols="12" sm="6" class="pa-6">
      <v-text-field
        v-model="name"
        :rules="nameRules"
        :label="$t('common.form_name')"
        class="input"
        name="name"
        required
      />
    </v-col>
    <v-col cols="12" sm="6" class="pa-6">
      <v-text-field
        v-model="email"
        :rules="emailRules"
        :label="$t('common.form_email')"
        class="input"
        name="email"
        required
      />
    </v-col>
  </v-row>
  <div class="btn-area">
    <div class="form-control-label">
      <v-checkbox
        v-model="checkbox"
        color="primary"
        :rules="[v => !!v || 'You must agree to continue!']"
        :label="$t('common.form_terms')"
        required
      />
      <a href="#">{{ $t('common.form_privacy') }}</a>
    </div>
    <v-btn
      color="primary"
      outlined
      @click="validate"
      large
      type="submit"
      value="Send message"
    >
      {{ $t('common.form_send') }}
      <v-icon class="right-icon">mdi-send</v-icon>
    </v-btn>
  </div>
</v-form>
0 голосов
/ 28 мая 2020

В итоге я выбрал немного другой путь, чтобы решить эту проблему. Я полагался на документы формы Vuetify , а также на статью Netlify об интеграции форм с Vue.

  <template>
    <v-form
      v-if="!submitted"
      ref="form"
      v-model="valid"
      name="contactForm"
      data-netlify="true"
      data-netlify-honeypot="bot-field"
      method="POST"
      @submit.prevent="submit">
      <input
        type="hidden"
        name="form-name"
        value="contactForm">
      <v-row>
        <v-col
          cols="12"
          md="6">
          <v-text-field
            v-model="form.firstName"
            color="primary"
            label="First Name *"
            outlined
            :rules="nameRules"
            required />
        </v-col>
        <v-col
          cols="12"
          md="6">
          <v-text-field
            v-model="form.lastName"
            color="primary"
            label="Last Name *"
            outlined
            :rules="nameRules"
            required />
        </v-col>
      </v-row>
      <v-row>
        <v-col cols="12">
          <v-text-field
            v-model="form.email"
            color="primary"
            label="Email *"
            type="email"
            :rules="emailRules"
            outlined
            required />
        </v-col>
      </v-row>
      <v-row justify="center">
        <v-col cols="12">
          <v-textarea
            v-model="form.message"
            color="primary"
            label="Message *"
            outlined
            :rules="nameRules"
            required />
        </v-col>
        <v-col
          sm="12"
          class="text-center">
          <v-btn
            :disabled="!valid || sendingForm"
            color="accent"
            depressed
            :ripple="false"
            x-large
            type="submit">
            {{ sendingForm ? 'Loading...' : 'Submit' }}
          </v-btn>
        </v-col>
      </v-row>
      <p class="d-none">
        <label for="bot-field">Don't fill this out: </label>
        <input
          type="text"
          name="bot-field">
      </p>
    </v-form>
  </template>

  <script>
    import axios from 'axios';

    export default {
      data: () => ({
        ...other stuff,
        emailRules: [
           v => !!v || 'E-mail is required',
           v => /.+@.+\..+/.test(v) || 'E-mail must be valid',
        ],
        form: {
          email: '',
          firstName: '',
          lastName: '',
          message: '',
        },
        nameRules: [
          v => !!v || 'Name is required.',
        ],
      }),

      methods: {
        encode (data) {
          return Object.keys(data)
           .map(
             key => `${encodeURIComponent(key)}=${encodeURIComponent(data[key])}`
           )
          .join("&");
        },
        submit () {
          this.sendingForm = true;

          const axiosConfig = {
            header: { 'Content-Type': 'application/x-www-form-urlencoded' }
          };

          axios
            .post(
              '/',
              this.encode({
                'form-name': 'contactForm',
                ...this.form
              }),
              axiosConfig
            )
            .then(() => this.submitted = true)
            .catch(err => console.log(err))
            .finally(() => this.sendingForm = false);
          }
       }
  </script>

Поскольку проверка выполняется с помощью required и :rules, мне не нужно вручную проверять его в функции отправки. И поскольку он привязан к Netlify Forms, мне нужно запустить ax ios POST с закодированными полями формы.

FWIW, я понял, что при ведении журнала консоли this.$refs форма кажется неопределенной. Однако, если я консолью журнал this.$refs.form, он дает мне ссылку, как и ожидалось.

...