How to validate Vuetify text field asynchronously?

我的梦境 提交于 2019-12-06 02:45:52

问题


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 validation could be made server-side using XHR?

Something like:

<v-text-field :rules="[v => { axios.get('/check?value=' + val).then(() => { return true }) }]">

回答1:


One solution is to set the error-messages prop:

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

and use the watch method:

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



回答2:


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



来源:https://stackoverflow.com/questions/49132167/how-to-validate-vuetify-text-field-asynchronously

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!