3
votes

I've been building a vue app and I'm currently building a component that has a "Person" object, and a few inputs fields to add information about that person, such as Name, address, email, etc. One of those fields is the mobile number, but a person can have more than one number, so I created a custom component that repeats the input field at will. This is roughly what it looks like. All those inputs are being validated using vee validate. This is roughly what is looks like:

     <!--createPerson.vue -->
     <div class="form-group">
        <input v-model="person.firstName" v-validate="'required'" data-vv-delay="500" name="first-name" type="text" placeholder="First name">
        <span v-show="errors.has('first-name')" class="input__error">{{ errors.first('first-name') }}</span>
    </div>

    <div class="form-group">
        <input v-model="person.lastName" v-validate="'required'" data-vv-delay="500" name="last-name" type="text" placeholder="Last name">
        <span v-show="errors.has('last-name')" class="input__error">{{ errors.first('last-name') }}</span>
    </div>

    <repeatable-inputs v-model="person.mobiles"  v-validate="'required'" data-vv-value-path="input" data-vv-name="mobile" type="tel" name="mobile" placeholder="Mobile" :inputmode="numeric" link-name="mobile number"></repeatable-inputs>

    <div class="form-group">
        <input v-model="person.email"  v-validate="'required|email'" data-vv-delay="500" name='email' type="text" placeholder="Personal email">
        <span v-show="errors.has('email')" class="input__error">{{ errors.first('email') }}</span>
    </div>

The person object, under the same createPerson.vue file, has a property called mobiles which starts as an empty array. It also has a validateAll() function, used as described in the vee-validate docs, that performs a validation of all inputs when clicking a "Next" button. Then, on the repeatableInputs.vue, there's this:

<template>
    <div>
        <div class="form-group" v-for="(input, index) in inputs">
            <input
                :type="type"
                :name="name+index"
                :placeholder="placeholder"
                :inputmode="inputmode"
                :value="input"
                @input="update(index, $event)"
                v-focus></input>

        </div>

        <a href="#" v-on:click.prevent="add">Add another {{linkName}}</a>


    </div>
    </template>

    <script>
        export default {
            props: {
                value: {
                    type: Array,
                    default: ['']
                },
                type: {
                    type:       String,
                    default:    "text"
                },

                name:           String,
                placeholder:    String,
                inputmode:      String,

                linkName: {
                    type:       String,
                    default:    "input"
                }
            },

            data: function () {
                return {
                    inputs: this.value
                }
            },
            methods: {
                add: function () {
                    this.inputs.push('');
                },

                update: function(index, e) {
                    this.inputs[index] = e.target.value;
                    this.$emit('input', this.inputs);
                }
            }
        }
    </script>

To be able to validate these custom inputs in the parent createPerson.vue, using the validateAll() function, the docs state that I must, quoting, Should have a data-vv-value-path attribute which denotes how to access the value from within that component (Needed for validateAll calls).

And this is where I got stuck. I'm not sure that that vv-path must point to, and I tried using 'value', ' input', 'inputs', creating a watch function, and a few other things that didn't even make much sense. I've found a git issue with validating custom inputs that used v-for, but that has apparently since been fixed.

1

1 Answers

1
votes

Data-vv-value-path should point to where the data is inside the component state. On your input you can bind the input content to data with a v-model -attribute and then the validator knows which property of the child component it needs to validate.

So data-vv-value-path points to the data inside the child component and the data will be automatically updated when bound with v-model.