我正在使用vue的项目中。目前,我正在开发对输入的验证,并以使其更加灵活的方式,我的想法是创建一个中间组件“ Group Component”,在其中将要加载的输入设置为属性。因此,验证将导入到组件中。
我发现很难理解几个输入何时通过了“页面组件”中没有错误的验证,针对这个问题,我想出了一个解决方案,我不知道这是否是理想的方法,因为我使用$ ref来获取子组件的验证,并在提交时验证所有组件是否通过。
我用于验证的软件包是vuelidate。
有更好的方法吗?
在“页面组件”上提交表单的验证
onSubmit() {
setTimeout(() => {
if (this.checkIfAllInputsFilled()) {
console.log('yes');
} else {
console.log('no');
}
, 300)
},
checkIfAllInputsFilled() {
let validationsObj = { email: this.$refs.email.$v.$invalid, password: this.$refs.password.$v.$invalid };
return Object.keys(validationsObj).every((k) => !validationsObj[k]);
}
所有文件-代码
页面组件
<template>
<div class="login">
<form class="login__form" @submit.prevent="onSubmit" novalidate>
<base-input-group
component="Input"
labelClass="authentication"
:labelValue="$t('global.email')"
inputId="email"
inputType="email"
inputName="email"
inputClass="input--default input--authentication"
inputValue=""
:contentErrors="[
{ key: 'required', message: $t('errors.gerals.required') },
{ key: 'email', message: $t('errors.gerals.invalid') }
]"
@get-value="form.email = $event"
ref="email"
/>
<div class="authentication__form__buttons display--flex">
<base-button
type="submit"
classAttribute="button--default button--background button--authentication"
:text="$t('authentication.login')"
/>
</div>
</form>
</div>
</template>
<script>
// components
const baseInputGroup = () => import( /* webpackChunkName: 'inputGroup' */ '../../../components/inputs/baseInputGroup');
const baseButton = () => import( /* webpackChunkName: 'baseButton' */ '../../../components/buttons/baseButton');
export default {
components: {
baseInputGroup: baseInputGroup,
baseButton: baseButton
},
data() {
return {
active: false,
form: {
email: ''
}
}
},
methods: {
onSubmit() {
setTimeout(() => {
if (this.checkIfAllInputsFilled()) {
console.log('yes');
} else {
console.log('no');
}
}, 300)
},
checkIfAllInputsFilled() {
let validationsObj = { email: this.$refs.email.$v.$invalid };
return Object.keys(validationsObj).every((k) => !validationsObj[k]);
}
}
}
</script>
组组件
<template>
<div class="field-group" :class="{'field--errors': $v.value.$error, 'field--success': !$v.value.$error}">
<label for="inputId" :class="`label label--${labelClass}`"> {{ labelValue }}</label>
<component
:is="componentInput"
:inputId="inputId"
:inputType="inputType"
:inputName="inputName"
:inputClass="inputClass"
:value="inputValue"
:valid="$v.value"
@input-value="value = $event"
/>
<component
v-if="$v.value.$error"
:is="componentErrors"
:errorMessage="errorMessage"
/>
</div>
</template>
<script>
export default {
props: {
component: String,
labelClass: String,
labelValue: String,
inputId: String,
inputType: String,
inputName: String,
inputClass: String,
inputValue: String,
contentErrors: Array
},
data () {
return {
componentInput: null,
componentErrors: null,
value: '',
validator: {},
errorMessage: ''
}
},
created() {
import(`../../../validations/${this.inputName}.js`).then( validator => {
this.validator = validator.default;
});
this.loaderComponent()
.then(() => { this.componentInput = () => this.loaderComponent(); })
},
methods: {
fillMessageError() {
this.contentErrors.map( error => {
if (!this.$v.value[error.key]) this.errorMessage = error.message;
});
}
},
computed: {
loaderComponent () {
return () => import( /* webpackChunkName: 'input' */ `./childrens/base${this.component}`);
},
loaderComponentErrors () {
return () => import( /* webpackChunkName: 'errors' */ './../errors/baseError');
}
},
validations () {
return {
value : {
...this.validator
}
}
},
watch: {
'$v.value.$error': {
deep: true, // so it detects changes to properties only
handler(newVal, oldVal) {
if (newVal) {
if (!this.componentErrors) {
this.loaderComponentErrors()
.then((component) => { this.componentErrors = () => this.loaderComponentErrors(); });
}
this.fillMessageError();
} else {
this.$emit('get-value', this.value)
}
}
}
}
}
</script>
输入组件
<template>
<input
:id="inputId"
:type="inputType"
:name="inputName"
:class="inputClass"
:value="inputValue"
@blur="action"
@keyup.enter="action"
>
</template>
<script>
export default {
props: {
inputId: String,
inputType: String,
inputName: String,
inputClass: String,
inputValue: String,
valid: Object,
},
methods: {
action($event) {
this.$emit('input-value', $event.target.value);
this.valid.$touch();
}
}
}
</script>