How to validate Vuetify text field asynchronously?

后端 未结 2 1718
走了就别回头了
走了就别回头了 2021-02-09 01:42

Text fields in Vuetify have rules props, which take an array of functions returning true or an error string. How to make them async, so that the valida

相关标签:
2条回答
  • 2021-02-09 01:42

    One solution is to set the error-messages prop:

    <v-text-field v-model="input" :error-messages="errors">

    and use the watch option:

    new Vue({
      data () {
        return {
          input: '',
          errors: []
        }
      },
      watch: {
        input (val) {
            axios.get('/check?value=' + val).then(valid => {
              this.errors = valid ? [] : ['async error']
            })
        }
      }
    });
    
    0 讨论(0)
  • 2021-02-09 02:09

    I have to do a backend validation to check if the username entered already exists. I use the swagger client library with the JSON open API v3 to call the method that checks the username value.

    So I solved in this way...

    In my login.js file I have defined a string property that contains the error message:

    import swaggerClient from "../remote-client";
    const strict = true;
    const state = {
      hasError: false,
      error: null,
      usernameAlredyExists: ""
    };
    const getters = {
      hasError: state => state.hasError,
      error: state => state.error,
      usernameAlredyExists: state => state.usernameAlredyExists
    };
    const mutations = {
      checkingUsername(state) {
        state.hasError = false;
        state.error = null;
        state.usernameAlredyExists = "";
      },
      usernameCheckedKO(state) {
        state.usernameAlredyExists = "Username already exists";
      },
      usernameCheckedOK(state) {
        state.usernameAlredyExists = "";
      },
      errorCheckingUsername(state, error) {
        state.hasError = true;
        state.error = error;
      },
    };
    const actions = {
      userLogin({ commit }, { username, password }) {
        // not relevant code
      },
      checkUsername({ commit }, { username }) {
        commit("checkingUsername");
        swaggerClient.userSwaggerClient
          .then(
            function(client) {
              return client.apis.UserHealthFacility.getHfUserUsernameWithUsername(
                { username: username },
                {},
                {}
              );
            },
            function(reason) {
              // failed to load the JSON specification
              commit("errorCheckingUsername", reason);
            }
          )
          .then(
            function(callResult) {
              if (callResult.body) {
                commit("usernameCheckedKO");
              } else {
                commit("usernameCheckedOK");
              }
            },
            function(reason) {
              // failed to call the API method
              commit("errorCheckingUsername", reason);
            }
          );
      }
    };
    
    export default {
      namespaced: true,
      strict,
      state,
      getters,
      mutations,
      actions
    };
    

    Then in the Login.vue file I have this code:

    <v-card-text>
      <v-form ref="loginForm" v-model="loginValid" lazy-validation>
        <v-text-field
          v-model="username"
          label="Username"
          :rules="[rules.required]"
          :error-messages="usernameAlredyExists"
          v-on:change="callCheckUsername"
        ></v-text-field>
        <v-text-field
          v-model="password"
          :label="Password"
          :append-icon="showPassword ? 'visibility_off' : 'visibility'"
          :type="showPassword ? 'text' : 'password'"
          :rules="[rules.required, rules.minLength]"
          counter
          @click:append="showPassword = !showPassword"
        ></v-text-field>
      </v-form>
    </v-card-text>
    <v-card-actions>
      <v-spacer></v-spacer>
      <v-btn
        :disabled="!loginValid"
        @click="callUserLogin"
        color="primary"
        round
      >Login</v-btn>
    </v-card-actions>
    
    <script>
    export default {
      data() {
        return {
          username: "",
          password: "",
          showPassword: false,
          loginValid: true,
          rules: {
            required: value => !!value || "Questo campo è obbligatorio",
            minLength: value =>
              value.length >= 8 || "Questo campo deve contenere almeno 8 caratteri"
          }
        };
      },
      computed: {
        usernameAlredyExists() {
          return this.$store.getters["login/usernameAlredyExists"];
        }
      },
      methods: {
        callUserLogin() {
          if (this.$refs.loginForm.validate()) {
            this.$store.dispatch("login/userLogin", {
              username: this.username,
              password: this.password
            });
          }
        },
        callCheckUsername(value) {
          if (value) {
            this.$store.dispatch("login/checkUsername", {
              username: this.username
            });
          }
        }
      }
    };
    </script>
    

    In this way it seems to work well

    0 讨论(0)
提交回复
热议问题