如何异步验证 Vuetify 文本字段?
Posted
技术标签:
【中文标题】如何异步验证 Vuetify 文本字段?【英文标题】:How to validate Vuetify text field asynchronously? 【发布时间】:2018-08-14 09:21:00 【问题描述】: Vuetify 中的Text fields 具有rules
属性,它采用返回true
或错误字符串的函数数组。如何使它们异步,以便使用 XHR 在服务器端进行验证?
类似:
<v-text-field :rules="[v => axios.get('/check?value=' + val).then(() => return true ) ]">
【问题讨论】:
好吧,你不能。至少不使用标准:rules
。它们只接受布尔值或字符串返回。
@acdcjunior 为什么不呢?他不是返回布尔值吗?
@Michael 他不是。 v => axios.get('/check?value=' + val).then(() => return true )
与 v => something();
相同,后者打开一个块并因此返回 undefined
。即使是(注意添加的return
):v => return axios.get('/check?value=' + val).then(() => return true )
它返回Promise<boolean>
,而不是boolean
。
【参考方案1】:
一种解决方案是设置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']
)
);
【讨论】:
为了避免副作用更喜欢在手表async input(val) this.errors = ['Vérification du code en cours ...']; const res = await axios.get('/check?value=' + val); // If value has been changed since start of function quit because result of last launched win if (val !== this.input) return if (res.data.valid) this.errors = []; else this.errors = ['Async error'];
【参考方案2】:
我必须进行后端验证以检查输入的用户名是否已经存在。我使用带有 JSON open API v3 的 swagger 客户端库来调用检查用户名值的方法。
所以我就这样解决了……
在我的 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>
这样看来效果不错
【讨论】:
以上是关于如何异步验证 Vuetify 文本字段?的主要内容,如果未能解决你的问题,请参考以下文章