我正在使用vuelidate来验证表单输入并使用vuetifyjs显示错误消息。我设法进行了基本的对象验证,并能够显示错误消息。
但是,当我验证集合时,我在显示错误消息时遇到问题。
问题
示例数据结构:
contact: {
websites: [
{
url: 'http://www.something.com',
label: 'Website',
}
]
}
验证示例:
validations: {
websites: {
$each: {
url: {
url,
}
}
},
}
示例模板:
<template v-for="(website, index) in websites">
<v-layout row :key="`website${index}`">
<v-flex xs12 sm9 class="pr-3">
<v-text-field
label="Website"
:value="website.url"
@input="$v.websites.$touch()"
@blur="$v.websites.$touch()"
:error-messages="websiteErrors"
></v-text-field>
</v-flex>
</v-layout>
</template>
计算错误消息示例:
websiteErrors() {
console.log('websites',this.$v.websites) // contains $each
const errors = []
if (!this.$v.websites.$dirty) {
return errors
}
// Issue is that all of them show must be valid, even if they are valid.
// Validation is basically broken.
// I also tried this.$v.websites.$each.url
!this.$v.websites.url && errors.push('Must be valid url')
return errors
},
示例方法(更新,也尝试了带有传递索引的方法):
websiteErrors(index) {
console.log('this.$v.entity.websites', this.$v.entity.websites.$each.$iter, this.$v.entity.websites.$each.$iter[index], this.$v.entity.websites.minLength, this.$v.entity.websites.$each.$iter[index].url)
const errors = []
if (!this.$v.entity.websites.$dirty) {
return errors
}
!this.$v.entity.websites.$each.$iter[index].url && errors.push('Must be valid url')
return errors
},
但是,当我这样做时,它始终是真实的,因此永远不会显示错误。
期望
我希望有一个与vuelidate sub-collection validation中所示的示例相同的示例,不同之处在于,不是循环进入我想以编程方式生成消息的模板。
参考
由vuelidate提供的示例:
import { required, minLength } from 'vuelidate/lib/validators'
export default {
data() {
return {
people: [
{
name: 'John'
},
{
name: ''
}
]
}
},
validations: {
people: {
required,
minLength: minLength(3),
$each: {
name: {
required,
minLength: minLength(2)
}
}
}
}
}
<div>
<div v-for="(v, index) in $v.people.$each.$iter">
<div class="form-group" :class="{ 'form-group--error': v.$error }">
<label class="form__label">Name for {{ index }}</label>
<input class="form__input" v-model.trim="v.name.$model"/>
</div>
<div class="error" v-if="!v.name.required">Name is required.</div>
<div class="error" v-if="!v.name.minLength">Name must have at least {{ v.name.$params.minLength.min }} letters.</div>
</div>
<div>
<button class="button" @click="people.push({name: ''})">Add</button>
<button class="button" @click="people.pop()">Remove</button>
</div>
<div class="form-group" :class="{ 'form-group--error': $v.people.$error }"></div>
<div class="error" v-if="!$v.people.minLength">List must have at least {{ $v.people.$params.minLength.min }} elements.</div>
<div class="error" v-else-if="!$v.people.required">List must not be empty.</div>
<div class="error" v-else-if="$v.people.$error">List is invalid.</div>
<button class="button" @click="$v.people.$touch">$touch</button>
<button class="button" @click="$v.people.$reset">$reset</button>
<tree-view :data="$v.people" :options="{rootObjectKey: '$v.people', maxDepth: 2}"></tree-view>
</div>
答案 0 :(得分:2)
错误之处
vuelidate $each.$iter
位置:将其从计算的错误消息移至v-for
解决方案
这是解决方法(固定1和3):
<template v-for="(v, index) in $v.websites.$each.$iter">
<v-layout row :key="`website${index}`">
<v-flex xs12 sm9 class="pr-3">
<v-text-field
label="Website"
:value="v.$model.url"
@input="$v.websites.$touch()"
@blur="$v.websites.$touch()"
:error-messages="v.$dirty && !v.required ? ['This field is required'] : !v.url ? ['Must be a valid url'] : []"
/>
</v-flex>
</v-layout>
</template>
这是我现在的更新方法(修复2):
updateWebsite(index, $event) {
const websites = [...this.websites];
websites[index] = $event;
this.updateVuex(`websites`, websites)
this.$v.websites.$touch()
},
最初是这样的:
updateWebsite(index, $event) {
this.updateVuex(`websites[${index}]`, $event)
this.$v.websites.$touch()
},
替代
还有另一种选择,在这种情况下将website
包装在组件内部。这样,您可以保留计算出的错误消息,因为它不会被共享。