Search code examples
typescriptvue.jsvuejs3vee-validatevue-composition-api

VeeValidate 4 validate without submit button


I'm trying to wrap my head around VeeValidate 4 but it's quite different from the previous version so I run in to a lot of question marks and obstacles. I work with a Vue 3 app, using the composition API, with a couple of forms in different components/views. There is a "Next page" button which takes you to the next view, but as that button is lying completely separate from the forms I don't have any handleSubmit connected to the forms. Instead I want to keep it in the state if the current form is valid or not, and that way determine if the user is allowed to go to the next page.

What I would like to accomplish, but am not sure if I can, is to be able to "hook into" when the field validations are happening and that way save to the state if all form fields are valid or not. I've looked through the documentation many times but I can't figure it out. I would greatly appreciate any kind of help, tips or thoughts.

This is a simplified version of one of my Vue components/views:

<template>
    <form>
        <CustomInput v-model="name" inputType="text" name="name" />
        <div v-if="nameErrors.length">{{ nameErrors[0] }}</div>

        <CustomInput v-model="width" inputType="text" name="width" />
        <div v-if="widthErrors.length">{{ widthErrors[0] }}</div>
    </form>
</template>

<script lang="ts">
import { defineComponent } from 'vue';
import { useField } from 'vee-validate';
import CustomInput from 'CustomInput.vue';

export default defineComponent({
    name: 'View',
    components: {
        CustomInput,
    },
    setup() {
        const { value: name, errors: nameErrors } = useField('name', 'required');
        const { value: width, errors: widthErrors } = useField('width', 'required|numeric|boatWidth');

        return {
            name,
            width,
            nameErrors,
            widthErrors,
        };
    },
});
</script>

Component hiearchy:

LayoutComponent
    FormComponent (which component depends on what step the user is on)
    NextButtonComponent

Solution

  • You should use the useForm function to gain access to the form state. You can use inject/provide for that:

    // in parent component
    const { meta, errors } = useForm();
    
    provide('form_meta', meta);
    provide('form_errors', errors);
    

    Then in your child components you can inject these properties:

    const formMeta = inject('form_meta');
    const formErrors = inject('form_errors');