这是我第一次尝试在前端使用 joi,我面临的问题是当我尝试使用错误数据时,我没有收到自定义错误。
这是我的代码
validation.js
import Joi from "joi";
export const loginSchema = Joi.object({
email: Joi.string()
.pattern(new RegExp("^[^@\\s]+@[domainName]\\.(com|in)$"))
.email({
minDomainSegments: 2,
tlds: { allow: ["com", "in"] },
})
.required()
.messages({
"string.email": "Email must be a valid email",
"string.pattern.base":
"Email domain must be [domainName] and end with .com or .in",
"any.required": "Email is a required field",
}),
password: Joi.string()
.pattern(new RegExp("^[a-zA-Z0-9]{3,30}$"))
.required()
.messages({
"string.base": "Password should be a type of text",
"string.empty": "Password cannot be an empty field",
"string.pattern.base":
"Password should have a minimum length of 3 and a maximum length of 30, and contain only letters and numbers",
"any.required": "Password is a required field",
}),
});
对于前端,我使用的是 Ionic Vue 版本 8,这是该文件中的关键代码,因为它太长了;
<!-- Email -->
<ion-item>
<ion-input
placeholder="Email Address"
label-placement="stacked"
color="light"
type="email"
v-model.trim="form.email"
@ionBlur="validateField('email')"
:error-text="errors.email"
>
<ion-icon
slot="start"
:icon="mailOutline"
aria-hidden="true"
></ion-icon>
</ion-input>
</ion-item>
<!-- Password -->
<ion-item>
<ion-input
placeholder="Password"
label-placement="stacked"
color="light"
type="password"
v-model.trim="form.password"
@ionBlur="validateField('password')"
:error-text="errors.password"
>
<ion-icon
slot="start"
:icon="keyOutline"
aria-hidden="true"
></ion-icon>
<ion-input-password-toggle
slot="end"
color="dark"
></ion-input-password-toggle>
</ion-input>
</ion-item>
<script setup>
import { loginSchema } from "../../services/Validators";
import { reactive } from "vue";
const form = reactive({
email: "",
password: "",
});
const errors = reactive({
email: null,
password: null,
});
const validateField = (field) => {
const data = { [field]: form[field] };
console.log("Data: ", { ...data });
console.log("datatype: ", typeof data[field]);
const schema = loginSchema.extract(field);
const { error } = schema.validate(
{ email: data[field] },
{ abortEarly: false }
);
console.log(`Validation error for ${field}:`, { ...error });
errors[field] = error ? error.details[0].message : null;
};
</script>
有人可以指导我这里出了什么问题吗,因为当我用一些错误的电子邮件记录错误时,这是我得到的日志
{
"_original": {
"email": "[email protected]"
},
"details": [
{
"message": "\"value\" must be a string",
"path": [],
"type": "string.base",
"context": {
"label": "value",
"value": {
"email": "[email protected]"
}
}
}
]
}
理想情况下应该记录的是:
"string.pattern.base": "Email domain must be [domainName] and end with .com or .in",
最初,我虽然可能没有发送正确的数据格式或数据类型格式,但是当我打印该字段的
data
和 dataType
时,这就是我所看到的
data
{
"email": "[email protected]"
}
dataType
datatype: string
电子邮件验证错误:
{
"_original": {
"email": "[email protected]"
},
"details": [
{
"message": "\"value\" must be a string",
"path": [],
"type": "string.base",
"context": {
"label": "value",
"value": {
"email": "[email protected]"
}
}
}
]
}
由于我使用的是 Joi.object(),其中键与架构键匹配,并且值是要验证的数据,所以我排除了这是由于不正确的数据类型或值造成的。
当我使用在线工具/沙箱测试此模式时,它工作得很好,但是当我在项目中运行它时却不然。我确信我忽略了一些东西,请帮我找出来
提取模式时无法传递对象,因此只需传递电子邮件字符串即可工作
let email = data[field];
const { error } = schema.validate(
email,
{ abortEarly: false }
);