简体   繁体   中英

How do I use vuelidate with an array of objects?

I have an array of objects that I loop through in my form questionnaire. There are five properties in each object, but only one property requires validation. I set up the validations part of the component as below:

specificGifts: {
      $each: {
        passThrough: {
          required: requiredIf(function(value) {
            return this.docs.includes('Will')
          })
        }
      }
    },

I saw on vuelidate documents that in my form html, instead of doing the following code below:

<div
              v-for="(gift, i) in specificGifts"
              :key="i"
            >
<v-select
                label="How does this specific gift pass if the recipient does not survive?"
                v-model="gift.passThrough"
                :items="specificGiftPassThrough"
              ></v-select>
    </div>

I should use:

<div
              v-for="(gift, i) in $v.specificGifts.$each.$iter"
              :key="i"
            >
<v-select
                label="How does this specific gift pass if the recipient does not survive?"
                v-model="gift.passThrough.$model"
                :items="specificGiftPassThrough"
              ></v-select>
    </div>

The data part of my vuejs component is as follows:

data(){
return{
specificGifts: []
}
}

However, I then get the following console error "Cannot read property $model of undefined". When I console.log $v.specificGifts.$each.$iter, I also get console errors. Does anyone know what I am doing wrong? Is there a better way to use validation? It seems vuelidate may not be up to speed in that it requires me to hardcode loop through a $v property just so I can use vuelidate, anyhow.

I've been facing the validation of a survey and want to share my solution.

My specific case is I have many questions and any of them has many answers (a group of radio buttons). My objective is to validate every question so that for each, one radio must be checked.

First I get the questions array of objects from API (my "value" properties are different):

[
     {
        "value":"a",
        "name":"first question",
        "answers":[
           {
              "label":"first answer",
              "value":"a1"
           },
           {
              "label":"second answer",
              "value":"a2"
           },
           ...
        ]
     },
     {
        "value":"b",
        "name":"second question",
        "answers":[
           {
              "label":"first answer",
              "value":"b1"
           },
           {
              "label":"second answer",
              "value":"b2"
           },
           ...
        ]
     }
     ...
]

Then, after getting the API response, I prepared another array of objects for the answers:

this.questions.map(function (item) {
  return {
    questionId: item.value,
    answerId: null
  };
})

the result is this structure:

[
    {
        questionId: 'a',
        answerId: null,
    },
    {
        questionId: 'b',
        answerId: null,
    }
    ...
]

I used quasar framework for the template but I think you can reproduce this logic with basic html:

  <q-field v-for="(question, key) in questions" :key="question.value"
    filled
    :label="question.name"
  >
    <template v-slot:control>
      <q-option-group
        v-model="answers[key].answerId"
        :options="question.answers"
        type="radio"
      />
    </template>
  </q-field>

Finally my validation rule is:

validations: {
  answers: {
    $each: {
      answerId: {
        required
      }
    }
  }
}

i've also had a lot of trouble with Vuelidate. The best solution i can give you is to change from Vuelidate to VeeValidate .

It's not complicated to change and it's going to save you a lot of time in the long run.

VeeValidate offers a lot of easy ways to use validation including custom Messages for each rule (no more computed's to give error messages) and allow's you to use rules depending on certain conditions.

You can check the documentation here

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM