如何在VueJS中使用计算属性映射嵌套的Vuelidate验证对象?

huangapple go评论76阅读模式
英文:

How to map a nested Vuelidate validation object with computed properties in VueJS?

问题

我有一个带有多个表单的选项卡容器。所有表单中的一些字段具有一些复杂的逻辑,我不想在每个表单上重复,所以我创建了一个自定义组件,该组件在所有表单中使用。我尝试使用 Vuelidate 来验证所有我的表单,但由于这些字段的名称相同,而且当然具有相同的验证逻辑,因此所有表单中的 Vuelidate 验证对象都是相同的,这意味着,如果我在表单A中填写了email字段,那么所有具有相同字段的表单也将正确验证,即使其他表单根本没有填写。

我尝试将我的验证包装在以表单名称命名的对象中,这似乎正确地分离了所有验证逻辑,但是,我在其中有其他设置,阻止我使用data属性,而我改用computed属性。据我所知,验证对象必须匹配我们访问字段数据的方式,比如,data() { formA: { email } }将与验证对象validations: { formA: { email } }匹配,问题是,由于我不使用data属性,我不知道如何映射计算属性。

这是我目前的代码:

  export default {
    components: { PhoneField, TopNote, SubmitButton, NameFieldsGroup, EmailField },
    validations: {
      formA: {
        firstName: { required },
        lastName: { required },
        email: {
          required,
          email
        },
        phone: {
          required,
          length: minLength(10)
        }
      }
    },
    created() {
      this.$store.commit('setFormValidation', this.$v);
    },
    data() {
      return {}
    },
    computed: {
      firstName: function() {
        return this.$store.getters.formState.firstName;
      },
      lastName: function() {
        return this.$store.getters.formState.lastName;
      },
      email: function() {
        return this.$store.getters.formState.email;
      },
      phone: function() {
        return this.$store.getters.formState.phone;
      }
    }
  };

我已经在过去的几天里一直在尝试,但是无法解决。有人可以为此提供解决方案吗?

英文:

I have a tabs container with multiple forms. Some of the fields in all forms have some complex logic that I didn't want to repeat on each form, so I created a custom component that is used in all forms. I'm trying to use Vuelidate to validate all of my forms but since those field names are the same, and of course have the same validation logic, the Vuelidate validation object is the same in all forms, meaning, if I fill in the email field in formA, then all forms with that same field will also validate correctly, even though the rest of the forms haven't been filled in at all.

I tried to wrap my validations inside an object named as the forms, and this seems to separate all validation logic correctly, but, I have other setup there that prevents me from using data attributes and I use computed attributes instead. As far as I know, the validations object must match the way we access fields data, like, data() { formA: { email } } would match to validation object validations: { formA: { email } }, the problem is, since I'm not using data properties, I don't know how to map computed properties.

This is what I have:

  export default {
    components: { PhoneField, TopNote, SubmitButton, NameFieldsGroup, EmailField },
    validations: {
      formA: {
        firstName: { required },
        lastName: { required },
        email: {
          required,
          email
        },
        phone: {
          required,
          length: minLength(10)
        }
      }
    },
    created() {
      this.$store.commit('setFormValidation', this.$v);
    },
    data() {
      return {}
    },
    computed: {
      firstName: function() {
        return this.$store.getters.formState.firstName;
      },
      lastName: function() {
        return this.$store.getters.formState.lastName;
      },
      email: function() {
        return this.$store.getters.formState.email;
      },
      phone: function() {
        return this.$store.getters.formState.phone;
      }
    }
  };

I've been messing around with this for the past several days, but can't figure it out. Anyone can suggest a solution for this?

答案1

得分: 2

以下是翻译好的部分:

找到了。不确定为什么有效,但现在有效了。修复方法是使用 Vuex 的 mapState,如下所示:

import { mapState } from 'vuex';

export default {
    components: { PhoneField, TopNote, SubmitButton, NameFieldsGroup, EmailField },
    validations: {
      formA: {
        firstName: { required },
        lastName: { required },
        email: {
          required,
          email
        },
        phone: {
          required,
          length: minLength(10)
        }
      }
    },
    created() {
      this.$store.commit('setFormValidation', this.$v);
    },
    data() {
      return {}
    },
    computed: {
      ...mapState(['formA']),
      firstName: function() {
        return this.$store.getters.formState.firstName;
      },
      lastName: function() {
        return this.$store.getters.formState.lastName;
      },
      email: function() {
        return this.$store.getters.formState.email;
      },
      phone: function() {
        return this.$store.getters.formState.phone;
      }
    }
  };

希望这对你有所帮助。

英文:

Figured it out. Not sure why it works but it does now. The fix is to use Vuex's mapState like this:

import { mapState } from 'vuex';

export default {
    components: { PhoneField, TopNote, SubmitButton, NameFieldsGroup, EmailField },
    validations: {
      formA: {
        firstName: { required },
        lastName: { required },
        email: {
          required,
          email
        },
        phone: {
          required,
          length: minLength(10)
        }
      }
    },
    created() {
      this.$store.commit('setFormValidation', this.$v);
    },
    data() {
      return {}
    },
    computed: {
      ...mapState(['formA']),
      firstName: function() {
        return this.$store.getters.formState.firstName;
      },
      lastName: function() {
        return this.$store.getters.formState.lastName;
      },
      email: function() {
        return this.$store.getters.formState.email;
      },
      phone: function() {
        return this.$store.getters.formState.phone;
      }
    }
  };

huangapple
  • 本文由 发表于 2020年1月7日 02:16:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/59616974.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定