在前端使用 Joi 包时无法抛出自定义错误消息

问题描述 投票:0回答:1

这是我第一次尝试在前端使用 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(),其中键与架构键匹配,并且值是要验证的数据,所以我排除了这是由于不正确的数据类型或值造成的。

当我使用在线工具/沙箱测试此模式时,它工作得很好,但是当我在项目中运行它时却不然。我确信我忽略了一些东西,请帮我找出来

javascript node.js vue.js joi ionic-vue
1个回答
0
投票

提取模式时无法传递对象,因此只需传递电子邮件字符串即可工作

 let email = data[field];
 const { error } = schema.validate(
    email,
    { abortEarly: false }
 );
© www.soinside.com 2019 - 2024. All rights reserved.