如何异步验证Vuetify文本字段?

时间:2018-03-06 13:36:43

标签: vue.js vuejs2 vuetify.js

Vuetify中的

Text fieldsrules个道具,它会返回一个返回true的函数数组或一个错误字符串。如何使它们异步,以便可以使用XHR在服务器端进行验证?

类似的东西:

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

2 个答案:

答案 0 :(得分:5)

一种解决方案是设置error-messages道具:

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

并使用watch方法:

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

答案 1 :(得分:-1)

我必须进行后端验证,以检查输入的用户名是否已经存在。我将swagger客户端库与JSON开放API v3一起使用,以调用检查用户名值的方法。

所以我以这种方式解决了...

在我的login.js文件中,我定义了一个字符串属性,其中包含错误消息:

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

然后在Login.vue文件中,我有以下代码:

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

这样看来效果很好