Vuelidate 服务器端验证

Vuelidate server side validation

我正在尝试结合前端和后端验证。

例如,在用户输入电子邮件的注册表单上,前端有一个 email 验证器,后端有一个 unique 验证器。

如果后端失败,则错误消息将保存到 requestErrorMessage 中的存储中。

{'email': 'A user with this email already exists.'}

请求中的电子邮件值也保存在 errorValues 字典中,以便在输入更改为不同的值时自动删除错误。

    mixins: [validationMixin],
    validations: {
        email: { required, email },
        password: { required, minLength: minLength(8) },
        password1: { required, sameAsPassword: sameAs('password') }
    },

    data() {
        return {
            email: '',
            password: '',
            password1: '',

            errorValues: {},
            errorFields: [
                'email',
                'password',
                'password1'
            ]
        }
    },

emailErrors() 检查服务器是否有错误。如果存在,则它会添加到任何现有错误中,但前提是输入值与发出请求时的值相同(存储在 errorValues 中)。

    computed: {
        ...mapGetters('auth', ['requestErrorMessage']),
        emailErrors() {
            let errors = []
            const field = 'email'
            const serverError =
                Object.keys(this.requestErrorMessage).includes(field) &&
                this[field] === this.errorValues[field]

            if (!this.$v[field].$dirty) return errors
            !this.$v[field].email && errors.push('Must be valid email')
            !this.$v[field].required && errors.push('Email is required')
            if (serverError)
                errors = errors.concat(this.requestErrorMessage[field])
            return errors
        }
    },

所以上面的一切都按预期工作,但错误是不可见的,直到用户更改输入然后将其更改回匹配 errorValues.email。换句话说,似乎 this.$v.$touch() 不起作用。

    methods: {
        ...mapActions('auth', ['register']),
        handleSubmit() {
            const data = {
                email: this.email,
                password: this.password,
                password1: this.password1
            }
            this.register(data).then(success => {
                if (!success) {
                    Object.keys(this.requestErrorMessage).forEach(key => {
                        if (this.errorFields.includes(key)) {
                            this.errorValues[key] = this[key]
                        }
                    })
                    this.$v.$touch()
                }
            })
        }
    }

如何在用户不手动修改输入的情况下让返回 promise 后显示服务器验证错误?

在调用 $touch.

之前,只需 $reset 为所有 children 到 false 设置 $dirty 标志
    this.register(data).then(success => {
            if (!success) {
                Object.keys(this.requestErrorMessage).forEach(key => {
                    if (this.errorFields.includes(key)) {
                        this.errorValues[key] = this[key]
                    }
                })
                this.$v.$reset()
                this.$v.$touch()
            }
        })