最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to properly add custom validation to array in vuelidate - Stack Overflow

programmeradmin4浏览0评论

I have an array of objects with the following structure

varientSections: [
    {
      type: "",
      values: [
        {
          varientId: 0,
          individualValue: ""
        }
      ]
    }
  ]

I created a custom validation called isDuplicate, which checks for duplicate value for the property "type". For example

varientSections: [
    {
      type: "Basket",
      values: [
        {
          varientId: 0,
          individualValue: ""
        }
      ]
    },
    {
      type: "Basket", // ERROR: Duplicate with the "above" object
      values: [
        {
          varientId: 1,
          individualValue: ""
        }
      ]
    }
  ],

I was able to get my custom validation to work. However, the $invalid property will be false for all the objects present in the array. Hence, all the objects in the array will be highlighted in red

Below is my validation code:

validations: {
varientSections: {
  $each: {
    type: {
      required,
      isDuplicate(type, varient) {
        console.log(varient);
        const varientIndex = this.varientSections.findIndex(
          v => v.type === type
        );

        var isWrong = true;
        this.varientSections.forEach((varObject, index) => {
          if (index !== varientIndex) {
            if (varObject.type === varient.type) {
              isWrong = false;
            }
          }
        });

        return isWrong;
      }
    },
    values: {
      $each: {
        individualValue: {
          required
        }
      }
    }
  }
}
},

I have an array of objects with the following structure

varientSections: [
    {
      type: "",
      values: [
        {
          varientId: 0,
          individualValue: ""
        }
      ]
    }
  ]

I created a custom validation called isDuplicate, which checks for duplicate value for the property "type". For example

varientSections: [
    {
      type: "Basket",
      values: [
        {
          varientId: 0,
          individualValue: ""
        }
      ]
    },
    {
      type: "Basket", // ERROR: Duplicate with the "above" object
      values: [
        {
          varientId: 1,
          individualValue: ""
        }
      ]
    }
  ],

I was able to get my custom validation to work. However, the $invalid property will be false for all the objects present in the array. Hence, all the objects in the array will be highlighted in red

Below is my validation code:

validations: {
varientSections: {
  $each: {
    type: {
      required,
      isDuplicate(type, varient) {
        console.log(varient);
        const varientIndex = this.varientSections.findIndex(
          v => v.type === type
        );

        var isWrong = true;
        this.varientSections.forEach((varObject, index) => {
          if (index !== varientIndex) {
            if (varObject.type === varient.type) {
              isWrong = false;
            }
          }
        });

        return isWrong;
      }
    },
    values: {
      $each: {
        individualValue: {
          required
        }
      }
    }
  }
}
},
Share Improve this question asked Jul 9, 2019 at 2:20 IssakiIssaki 1,0642 gold badges21 silver badges37 bronze badges 3
  • 2 use $each[index] in template – Christhofer Natalius Commented Jul 9, 2019 at 2:22
  • Hi @ChristhoferNatalius thanks for the reply! What do you mean by that? – Issaki Commented Jul 9, 2019 at 2:23
  • I found the official guide here: vuelidate.js/#sub-collections-validation . Should be suitable for your case, have a look first. – jet_choong Commented May 21, 2020 at 10:08
Add a ment  | 

4 Answers 4

Reset to default 6

Should be something like this.

<div v-for="(vs, index) in varientSections" :key="index">
    <input :class="{'is-error': $v.varientSections.$each[index].type.$error}" type="text" v-model="vs.type">
    <input :class="{'is-error': $v.varientSections.$each[index].value.$error}" type="text" v-model="vs.value>
</div>

Change the error class to fit your need.

In vue3 posable you should use helpers.forEach function:

import { useVuelidate } from "@vuelidate/core";  
import { helpers, required } from "@vuelidate/validators";

const form = reactive({
  users: [
    {
      name: "John"
      value: "Doe"
    }
  ]
})

const rules = {
  users: {
    $each: helpers.forEach({
      name: { required },
      value: { required }
    })
  }
}

const $v = useVuelidate(rules, form)

I had the exact same need and found that the solution was quite simple once you wrap your head around what you're trying to do. Your validator needs to trigger only if the current item is a duplicate of any previous items.

Something like this:

validations: {
  varientSections: {
    $each: {
      isUnique(currItem, itemArr) {
        // Find the index of the first item in the array that has the same type
        var firstIdx = itemArr.findIndex((item /*, index, arr*/) =>  currItem.type === item.type );
        // If it's the same as the current item then it is not a duplicte
        if(currItem === itemArr[firstIdx])
          return true;
        // All others are considered duplicates
        return false;
      },
      type: { required }
    }
  }
}

this is worked for me

 <b-row v-for="(field,index) in fields" :key="index">
   <b-colxx lg="6">
     <b-form-group :label="$t('target.name')">
       <b-form-input v-model="field.name" :state="!$v.fields.$each[index].name.$error"/>
       <b-form-invalid-feedback v-if="!$v.fields.$each[index].name.required">name is    required</b-form-invalid-feedback>


     </b-form-group>

   </b-colxx>
   <b-colxx lg="6">
     <b-form-group :label="$t('target.value')">
       <b-form-input v-model="field.value" :state="!$v.fields.$each[index].value.$error"/>
       <b-form-invalid-feedback v-if="!$v.fields.$each[index].value.required">value is    required</b-form-invalid-feedback>
     </b-form-group>
   </b-colxx>
 </b-row> 
 

.

 data() { 
      return {
          fields: [
                    {name: null, value: null},
                    {name: null, value: null} ]  
              } 
           }, 

.

validations: {
          fields: {
           $each: {
             name: {
               required
             },
             value: {
               required
             }
           }
   
   
       },
     },
发布评论

评论列表(0)

  1. 暂无评论