VeeValidate 附加方法:当字段有名称时,字段缺少 "name" 或 "data-vv-name" 属性
VeeValidate attach method: A field is missing a "name" or "data-vv-name" attribute when fields do have name
我有一个呈现个人详细信息组件的父组件,并且正在注入父组件的验证器范围。如果我使用 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 = '';
}
我想你可能想错了。理想情况下,验证逻辑应该在子组件中,而不是在父组件中。但是您应该 仍然能够使用父级来运行 验证。当您从父级注入验证器实例时,您应该能够将您的子组件更新为以下内容:
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();
并且它应该根据子组件中的规则进行验证。
通过使用 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
方法不起作用,但这个替代方法确实有效。
在我的例子中,data-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>`
我有一个呈现个人详细信息组件的父组件,并且正在注入父组件的验证器范围。如果我使用 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 = '';
}
我想你可能想错了。理想情况下,验证逻辑应该在子组件中,而不是在父组件中。但是您应该 仍然能够使用父级来运行 验证。当您从父级注入验证器实例时,您应该能够将您的子组件更新为以下内容:
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();
并且它应该根据子组件中的规则进行验证。
通过使用 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
方法不起作用,但这个替代方法确实有效。
在我的例子中,data-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>`