Typescript VeeValidate attach方法:一个字段缺少一个“";名称“;或;数据vv名称“;属性,当字段没有名称时

Typescript VeeValidate attach方法:一个字段缺少一个“";名称“;或;数据vv名称“;属性,当字段没有名称时,typescript,vuejs2,vee-validate,Typescript,Vuejs2,Vee Validate,我有一个呈现个人详细信息组件的父组件,并且正在注入父组件的验证器范围。如果我使用v-validate指令和this.$validator.validateAll()或this.$validator.validate('field_name')这可以正常工作 但是,我需要独立验证某些字段,但在使用this.$validator.attach('first_name','required')时,例如,我收到以下警告[vee validate]一个字段缺少“name”或“data vv name”属性

我有一个呈现个人详细信息组件的父组件,并且正在注入父组件的验证器范围。如果我使用
v-validate
指令和
this.$validator.validateAll()
this.$validator.validate('field_name')
这可以正常工作

但是,我需要独立验证某些字段,但在使用
this.$validator.attach('first_name','required')
时,例如,我收到以下警告
[vee validate]一个字段缺少“name”或“data vv name”属性
。我已尝试将用于附加验证器的调用移动到单击处理程序中,以防从
mounted()
调用时输入元素未完全呈现,但仍然会遇到相同的问题。我还分别尝试了
name
datavvname
属性

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');
    }

}
从“Vue属性装饰器”导入{Vue,组件};
从“./PersonalDetails”导入PersonalDetails组件;
@组成部分({
模板:`
`,
组成部分:{
PersonalDetails组件,
},
$\u veeValidate:{validator:'new'}
})
导出默认类ClaimComponent扩展Vue{
安装的(){
this.attachValidators();
}
把手按钮点击(){
这是。$validator.validateAll();
}
附件验证器(){
console.log(document.getElementsByName('first_name');//查找元素
此.$validator.attach('first_name','required');
此.$validator.attach(‘姓氏’、‘必需’);
此.$validator.attach('email','required');
}
}
个人资料

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 = '';

}
从“Vue属性装饰器”导入{Vue,组件,注入};
从“vee validate”导入{Validator};
@组成部分({
模板:`
名字
{{errors.first('first_name')}
姓
{{errors.first('姓氏')}
电子邮件地址
{{errors.first('email')}
`
})
导出默认类PersonalDetails组件扩展Vue{
@注入(“$validator”)公共$validator!:validator;
第一个名称:string='';
姓氏:string='';
电子邮件:string='';
}

我想你可能想错了。理想情况下,验证逻辑应该在子组件中,而不是在父组件中。但是您应该仍然能够使用父级运行验证。当您从父级注入验证程序实例时,您应该能够将子组件更新为以下内容:

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()并且它应该根据子组件中的规则进行验证。

我已经通过使用
数据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组件,
},
$\u veeValidate:{validator:'new'}
})
导出默认类ClaimComponent扩展Vue{
$refs!:{
personalDetails:personalDetails组件
}
把手按钮点击(){
这是.$refs.personalDetails.validateInput();
}
}
和个人详细信息组件:

@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'));
    }
}
@组件({
模板:`
名字
{{errors.first('first_name')}
姓
{{errors.first('姓氏')}
电子邮件地址
{{errors.first('email')}
`
})
导出默认类PersonalDetails组件扩展Vue{
@注入(“$validator”)公共$validator!:validator;
$refs!:{
名字:HTMLInputElement,
姓氏:HTMLInputElement,
电子邮件:HTMLInputElement
}
第一个名称:string='';
姓氏:string='';
电子邮件:string='';
公共验证输入(){
此.refs.firstName.dispatchEvent(新事件('validateStep');
此.$refs.name.dispatchEvent(新事件('validateStep');
此.$refs.email.dispatchEvent(新事件('validateStep');
}
}

我仍然不明白为什么
attach
方法不起作用,但是这个替代方法确实起作用。

在我的例子中,
数据vv name=“someName”
缺失。当您有两个类似的控件时,例如v-autocomplete,则同名字段将相互冲突,因此为了解决此问题,您可以使用
data vv name=“someName”
。 举例如下:

 <v-autocomplete
          v-model="id"
          :items="items"
          :label="$t('scheduling.fields.truck-id')"
          :placeholder="$t('common.words.none')"
          readonly
          :disabled="!canEdit"
          :append-icon="''">
 </v-autocomplete>`

 <v-autocomplete
          v-model="id2"
          :items="items2"
          :label="label2"
          :placeholder="$t('common.words.none')"
          readonly
          data-vv-name="someName"
          :disabled="!canEdit"
          :append-icon="''">
 </v-autocomplete>`

`
`

谢谢,关于验证逻辑在子组件中的观点很好。由于某种原因,虽然我仍然得到同样的答案