Vuejs-输入验证

时间:2019-06-12 14:13:17

标签: javascript forms validation vue.js

我正在使用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>

0 个答案:

没有答案