4

I'm working on a Vue front end for an application that requires all form data be persisted locally before submitting to the backend in case a network connection issue causes an interruption of service. I'm using Vuex to maintain all the form data across the application, so that it can be persisted and restored to/from local storage as required.

A second requirement is form validation, for which I intend to use the Vuelidate library. The documentation suggests that to use Vuelidate without a v-model, all that is required is this.$v.touch() in the event function. That is what I have tried, but it does not seem to work.

See the example below:

<template>
  <form>
    <input name="full-name" v-model="fullName" placeholder="Full Name" />
  </form>
</template>

<script>
  export default {
    name: "AForm"
    computed: {
      fullName: {
        get() { return this.$store.state.fullName }
        set(name) {
          this.$v.touch();
          this.$store.dispatch("updateFullName", name);
        },
      }
    },
    validations: {
      fullName: minLength(4);
    }
  }
</script>

When I examine $v.fullName, the value is just equal to true. When I look at the entire $v object, I see $anyDirty: false.

Codesandbox

tony19
  • 125,647
  • 18
  • 229
  • 307
richbai90
  • 4,994
  • 4
  • 50
  • 85
  • If i remember well in Vuelidate you need more then this to validate a form. There are examples in documentation too https://vuelidate.js.org/#sub-form-submission – Federico Provenziani Aug 01 '20 at 00:08

1 Answers1

4

Validation config malformed

The validation config should be:

export default {
  /**
   * Validation Config Format:
   *
   *   validations: {
   *     PROP_NAME: {
   *       RULE_NAME: RULE
   *     }
   *   }
   */
  validations: {
    //fullName: minLength(4), // DON'T DO THIS

    fullName: {
      minLength: minLength(4)
    }
  },
}

$touch

It looks like you used this.$v.touch(), but it's supposed to be this.$v.$touch(). However, since the computed prop sets only one prop, you should just invoke $touch() on that prop (i.e., $v.PROP_NAME.$touch()) after the prop is changed through the Vuex action.

export default {
  computed: {
    fullName: {
      get() {
        return this.$store.state.fullName;
      },
      set(name) {
        //this.$v.touch() // DON'T DO THIS

        this.$store.dispatch('updateFullName', name)
        this.$v.fullName.$touch()
      }
    }
  }
}

Edit Using Vuelidate with Vuex

tony19
  • 125,647
  • 18
  • 229
  • 307