Метод вложения VeeValidate: в поле отсутствует атрибут «name» или «data-vv-name», если поля имеют имя - PullRequest
0 голосов
/ 24 октября 2018

У меня есть родительский компонент, отображающий компонент личных данных, и я добавляю область действия родительского валидатора.если я использую директиву v-validate и this.$validator.validateAll() или this.$validator.validate('field_name'), это работает нормально.

Однако мне нужно проверить некоторые поля независимо, но при использовании, например, this.$validator.attach('first_name', 'required'), я получаю следующее предупреждение[vee-validate] A field is missing a "name" or "data-vv-name" attribute.Я попытался переместить вызов, чтобы присоединить валидаторы к обработчику щелчков, в случае, если элемент ввода не полностью отображается при вызове из mounted(), но все еще возникает та же проблема.Я также попробовал оба атрибута name или data-vv-name независимо.

Parent.ts

import { Vue, Component } from 'vue-property-decorator';

import PersonalDetailsComponent from './PersonalDetails';

@Component({
    template: `
        <div class="container">
            <personal-details-component></personal-details-component>

            <div class="row">
                    <Button :onClick="handleButtonClick" :buttonText="'Validate'"></Button>
            </div>
        </div>
    `,
    components: {
        PersonalDetailsComponent,
    },
    $_veeValidate: {validator: 'new'}
})
export default class ClaimComponent extends Vue {

    mounted() {
        this.attachValidators();
    }

    handleButtonClick() {
        this.$validator.validateAll();
    }

    attachValidators() {
        console.log(document.getElementsByName('first_name')); // Finds the element

        this.$validator.attach('first_name', 'required');
        this.$validator.attach('surname', 'required');
        this.$validator.attach('email', 'required');
    }

}

PersonalDetails.ts

import {Vue, Component, Inject} from 'vue-property-decorator';

import {Validator} from 'vee-validate';

@Component({
    template: `
    <div class="row">
        <div class="col-12">
            <form class="material-form">
                <div class="group w-third">
                    <input v-model="first_name" type="text" name="first_name" required>
                    <span class="highlight"></span>
                    <span class="bar"></span>
                    <label>First name</label>
                    <span class="form-text error-text">{{ errors.first('first_name') }}</span>
                </div>
                <div class="group w-third">
                    <input v-model="surname" type="text" name="surname" required>
                    <span class="highlight"></span>
                    <span class="bar"></span>
                    <label>Surname</label>
                    <span class="form-text error-text">{{ errors.first('surname') }}</span>
                </div>
                <div class="group w-third">
                    <input v-model="email" type="text" name="email" required>
                    <span class="highlight"></span>
                    <span class="bar"></span>
                    <label>Email address</label>
                    <span class="form-text error-text">{{ errors.first('email') }}</span>
                </div>
            </form>
        </div>
    </div>
    `
})
export default class PersonalDetailsComponent extends Vue {
    @Inject('$validator') public $validator!: Validator;

    first_name: string = '';
    surname: string = '';
    email: string = '';

}

Ответы [ 2 ]

0 голосов
/ 25 октября 2018

Мне удалось добиться того, что мне нужно - проверка определенных полей - с помощью атрибута data-vv-validate-on вместе с пользовательским событием.Таким образом, я могу запустить событие для любых входных данных, которые нужно проверить при нажатии кнопки.

Родительский компонент обновлен до:

@Component({
    template: `
        <div class="container">
            <personal-details-component ref="personalDetails"></personal-details-component>

            <div class="row">
                    <Button :onClick="handleButtonClick" :buttonText="'Validate'"></Button>
            </div>
        </div>
    `,
    components: {
        PersonalDetailsComponent,
    },
    $_veeValidate: {validator: 'new'}
})
export default class ClaimComponent extends Vue {
    $refs!: {
        personalDetails: PersonalDetailsComponent
    }

    handleButtonClick() {
        this.$refs.personalDetails.validateInput();
    }
}

И компонента PersonalDetails:

@Component({
    template: `
    <div class="row">
        <div class="col-12">
            <form class="material-form">
                <div class="group w-third">
                    <input v-model="first_name" ref="firstName" type="text" name="first_name"
                    v-validate="'required'" 
                    data-vv-validate-on="validateStep" required>
                    <span class="highlight"></span>
                    <span class="bar"></span>
                    <label>First name</label>
                    <span class="form-text error-text">{{ errors.first('first_name') }}</span>
                </div>
                <div class="group w-third">
                    <input v-model="surname" ref="surname" type="text" name="surname" 
                    v-validate="'required'"
                    data-vv-validate-on="validateStep" required>
                    <span class="highlight"></span>
                    <span class="bar"></span>
                    <label>Surname</label>
                    <span class="form-text error-text">{{ errors.first('surname') }}</span>
                </div>
                <div class="group w-third">
                    <input v-model="email" ref="email" type="text" name="email" 
                    data-vv-validate-on="validateStep" v-validate="'required|email'" 
                    required>
                    <span class="highlight"></span>
                    <span class="bar"></span>
                    <label>Email address</label>
                    <span class="form-text error-text">{{ errors.first('email') }}</span>
                </div>
            </form>
        </div>
    </div>
    `
})
export default class PersonalDetailsComponent extends Vue {
    @Inject('$validator') public $validator!: Validator;
    $refs!: {
        firstName: HTMLInputElement,
        surname: HTMLInputElement,
        email: HTMLInputElement
    }

    first_name: string = '';
    surname: string = '';
    email: string = '';

    public validateInput() {
        this.$refs.firstName.dispatchEvent(new Event('validateStep'));
        this.$refs.surname.dispatchEvent(new Event('validateStep'));
        this.$refs.email.dispatchEvent(new Event('validateStep'));
    }
}

Я до сих пор не понимаю, почему метод attach не работал, но эта альтернатива работает.

0 голосов
/ 24 октября 2018

Я думаю, что вы думаете об этом неправильно.В идеале логика проверки должна быть внутри дочернего компонента, а не родительского.Но вы должны по-прежнему иметь возможность использовать родительский элемент для запуска проверок.Поскольку вы внедряете экземпляр средства проверки подлинности из родительского объекта, вы должны иметь возможность обновить свой дочерний компонент следующим образом:

export default class PersonalDetailsComponent extends Vue {
    @Inject('$validator') public $validator!: Validator;

    first_name: string = '';
    surname: string = '';
    email: string = '';

    public mounted() {
        this.$validator.attach('first_name', 'required');
        this.$validator.attach('surname', 'required');
        this.$validator.attach('email', 'required');
    }
}

Затем вы можете удалить метод attachValidators из родительского элемента.Это должно прикрепить эти правила валидации к экземпляру валидатора, предоставленному родителем.Таким образом, теоретически родитель может запустить this.$validator.validateAll();, и он должен проверяться на основе правил в дочернем компоненте.

...