vuetify.js - 使用 TypeScript 和组合式 API 验证 vuetify 表单
我正在尝试在表单提交时进行验证,但在将我找到的示例转换为组合 API 和 TypeScript 时遇到了困难。使用选项 API 时,正确的语法似乎是
if (this.$refs.loginForm.validate()) {....}
并且使用组合式 API,其他帖子建议
if (loginForm.value.validate()) {....}
但是这给了我一个 TS 警告,提示该值可能为 null,更重要的是,即使表单是空提交,if() 条件总是成功的。
我的完整代码如下。valid 变量似乎没有任何影响,所以很明显我使用的方法还有其他问题。:
<script setup lang="ts">
import { ref } from 'vue'
const loginDialog = ref(false)
const userOrEmail = ref('');
const password = ref('');
const showPass = ref(false);
const loginForm = ref(null);
var valid = true;
const nameRules = [ (value: string) => !!value || 'Required.', ];
const pwRules = [ (value: string) => !!value || 'Required.', ];
function submit() {
if (loginForm.value?.validate())
{
alert("submitted");
loginDialog.value = false;
}
}
</script>
<template>
<v-dialog v-model="loginDialog" activator="parent" width="300">
<v-card>
<v-card-title class="headline black" primary-title>
Sign in
</v-card-title>
<v-card-text class="pa-5">
<v-form @submit.prevent="submit" ref="loginForm" v-model="valid" >
<v-text-field v-model="userOrEmail" :rules="nameRules" label="User name or email" hint="Username will be 3 to 10 characters">
</v-text-field>
<v-text-field v-model="password" :append-inner-icon="showPass ? 'mdi-eye' : 'mdi-eye-off'"
@click:append-inner="showPass = !showPass" :type="showPass ? 'text' : 'password'"
hint="password will be at least 6 characters"
:rules="pwRules" label="Password">
</v-text-field>
<v-btn color="blue" type="submit" block class="mt-2"> Sign in </v-btn>
</v-form>
</v-card-text>
</v-card>
</v-dialog>
</template>
我尝试将一个示例上传到 Vuetify Playground,但它无法运行,出现了一些我不理解的错误
答案#1
在 VForm 上调用 validate() 会返回一个 promise,因此你需要等待它解析:
async function submit() {
const {valid, errors} = await loginForm.value.validate()
if (valid) {
...
游乐场示例
请注意,当 VForm 接收到来自底层 <form> 元素的提交事件时,它会触发你通过模板引用调用的相同验证函数。然后,它将返回的 Promise 与提交事件合并为一个 SubmitEventPromise,并将其发送到 @submit(参见代码)。所以你实际上是在第二次调用 validate(并且可以不用模板引用):
async function submit(submitEventPromise: SubmitEventPromise) {
const {valid, errors} = await submitEventPromise
if (valid) {
...
游乐场示例
最后,VForm 有一个 :modelValue 属性,用于指示表单是否有效。与 validate() 函数不同,它是通过对已注册表单输入的观察者来设置的,当所有输入都已验证时会更新(见代码)。
因此,除非所有输入的验证已被手动触发,否则 @update:modelValue 事件只会在 validation() 完成后才会触发,而这本身就不足以替代 @submit 处理函数中的 SubmitEventPromise 参数。如果你想在 @submit 处理函数中依赖 :modelValue 而不等待该 promise,请确保 validate() 至少已完成一次,例如在表单加载时手动触发它。
游乐场示例
