【Ant Design Vue】Form表单组件的校验失效问题

2,227 阅读2分钟

使用 Form 表单组件的自定义校验规则时发现失效,或者出现以下错误: 不能读取未定义属性.PNG

解决方法

1. 解决校验规则失效问题

(1)在指定某一表单项的行内校验规则时需要在表单项<a-form-item>中添加name属性。

<a-form name="basic">
    <a-form-item 
        label="Username"
        name="username"
        :rules="[{ required: true, message: 'Please input your username!' }]"
    >
        <a-input 
            v-model:value="formState.username"
        />
    </a-form-item>
</a-form>

(2)在指定某一表单的校验规则对象时,表单项<a-form-item>不仅要添加name属性,其中name属性的值要与校验规则对象的属性名相同。

// 自定义校验规则对象
const rules = {
    // 校验规则对象的属性名要与name属性值一致
    username: [
        {
            required: true,
            message: "需要填写用户名",
            trigger: "blur",
        },
    ],

};
<a-form 
    name="basic"
    :rules="rules"
>
    <!-- 表单项的name属性值要与校验对象的属性名一致 -->
    <a-form-item 
        label="Username"
        name="username"
    >
        <a-input 
            v-model:value="formState.username"
        />
    </a-form-item>
</a-form>

2. 解决校验问题Cannot read properties of undefined(read 'length')

表单校验出现这个问题的原因:我认为是表单数据对象的属性名与校验规则的属性名不一样,对表单项信息进行校验时无法读取表单数据对象中的对应属性。例如:

定义表单数据对象、校验规则和校验方法

// 定义表单数据对象 loginInfo
const loginInfo = reactive({
    username: "",
    // 表单数据对象 loginInfo 的属性 pw 与校验规则中的属性 password 不一致,无法读取
    pw: "",
})

// 校验密码 方法(简略版)
const validatePass = async (_rule, value) => {
  // 校验
  if (value === "") {
    return Promise.reject("请输入密码!");
  } else if (value.length < 8) {
    return Promise.reject("密码长度不能少于8位!");
  }
};

// 定义自定义校验规则
const rules = {
    username: [
        {
            required: true,
            message: "需要填写用户名",
            trigger: "blur",
        },
    ],
    // 校验规则中的属性password
    password: [
        {
            required: true,
            validator: validatePass,
            trigger: "blur",
        },
    ],
};

定义表单

<a-form 
    name="basic"
    :rules="rules"
>
    <!-- 表单项的name属性值要与校验对象的属性名一致 -->
    <a-form-item 
        label="用户名"
        name="username"
    >
        <a-input 
            v-model:value="loginInfo.username"
        />
    </a-form-item>
    <a-form-item 
        label="密码"
        name="password"
    >
        <a-input-password 
            v-model:value="loginInfo.pw"
        />
    </a-form-item>
</a-form>

正确的校验流程是:当我们开始密码校验时,会调用校验规则对象rules的表单项规则rules.password的回调函数validatePass(),该回调函数接收表单数据对象loginInfo中属性 password 的值,并根据方法内定义的校验规则进行判断。

根据以上流程描述,就可以知道问题出现在哪一步了,即校验回调函数validatePass()读取表单数据对象loginInfo中属性 password 时没有读取到,因为原loginInfo并未声明该属性,所以读取到的是undefined,而undefined不存在 length 属性。

所以解决方法就是把表单数据对象loginInfo中属性pw修改成属性password。如下:

// 定义表单数据对象 loginInfo
const loginInfo = reactive({
    username: "",
    password: "",
})

以上都是我自身理解,如有问题,欢迎友友在评论区指出!