0

After reading documentation of Vee Validate 4 about using composition api with custom inputs, do I understand correctly that hook useField a have to call only inside input component(in my example is VInput.vue)? Is any way that i can use hook functionality in parent component? The VInput is used for another functionality that don't need validation so it will be extra functionality add useForm for global component in out project For example I have List.vue

<template>
 <form class="shadow-lg p-3 mb-5 bg-white rounded" @submit.prevent="submitPostForm">
        <VFormGroup label="Title" :error="titleError">
            <VInput v-model="postTitle" type="text" name="title" />
        </VFormGroup>
        <VFormGroup label="Body" :error="bodyError">
            <VInput v-model="postBody" type="text" name="body" />
        </VFormGroup>
        <button type="submit" class="btn btn-primary">Submit</button>
    </form>
</template>

<script>
import { ref, onMounted } from 'vue';
import { Form, useForm, useField } from 'vee-validate';
import * as Yup from 'yup';

export default {
    components: { Form },

    setup() {    
        const schema = Yup.object().shape({
           title: Yup.string().required(),
           body: Yup.string().min(6).required(),
        });

       //hooks
       const { handleSubmit } = useForm({ validationSchema: schema });

       // No need to define rules for fields because of schema
       const { value: postTitle, errorMessage: titleError } = useField('title');
       const { value: postBody, errorMessage: bodyError } = useField('body');

        //methods
        const submitPostForm = handleSubmit(() => {
         addPost({ title: postTitle, body: postBody });
        });

        return { schema, postTitle, postBody,  titleError, bodyError, submitPostForm };
    },
};
</script>

The problem that input error I have to show only in VFormGroup so how I can manage this form?

dmitriy
  • 488
  • 6
  • 25
  • related question https://stackoverflow.com/questions/66844224/vee-validate-4-validation-with-vuex-3-computed-property if you need to use existing reactive properties with usefield() – gagarine Jul 21 '21 at 09:03

1 Answers1

1

I am not sure if understood your question correctly. But in your case you only have 1 issue, you destructure errorMessage and value twice in one file, which isn't working.

you could change your useField's like this:

const { errorMessage: titleError, value: titleValue } = useField('title', Yup.string().required());
const { errorMessage: bodyError, value: bodyValue } = useField('body', Yup.string().required().min(8));

In your template you then want to use titleError and bodyError in your VFormGroup. In your VInput you want to use titleValue and bodyValue for v-model

because you initialise your title and body in your setup() I guess that those do not have any predefiend values. If that would be the case you might want to take a look at the Options for useField() where you can have as a thridParam as an Object with e.g. initialValue as key which then would be your post.value.title. But for your use case I wouldn't recommend this.

to answer the Code question from the comments:

<template>
 <form class="shadow-lg p-3 mb-5 bg-white rounded" @submit="handleSubmit">
        <VFormGroup label="Title" :error="titleError">
            <VInput v-model="titleValue" type="text" name="title" />
        </VFormGroup>
        <VFormGroup label="Body" :error="bodyError">
            <VInput v-model="bodyValue" type="text" name="body" />
        </VFormGroup>
        <button type="submit" class="btn btn-primary">Submit</button>
    </form>
</template>

<script>
import { ref } from 'vue';
import { Form, useForm, useField } from 'vee-validate';
import * as Yup from 'yup';

export default {
    components: { Form },
    setup() {    
        const title = ref('');
        const body = ref('');

       //hooks
       const { handleSubmit } = useForm();

       // No need to define rules for fields because of schema
       const { errorMessage: titleError, value: titleValue } = useField('title', Yup.string().required());
       const { errorMessage: bodyError, value: bodyValue } = useField('body', Yup.string().required().min(8));

        return { titleError, bodyError, titleValue, bodyValue, handleSubmit };
    },
};
</script>
Mirko t.
  • 481
  • 2
  • 11
  • But how I can combine my const post = ref({title: '', body: ''}) with hook const { errorMessage: titleError, value: post.title } = useField('title', Yup.string().required()); – dmitriy Jun 10 '21 at 09:46
  • I update my question's code with your working example - work everyting but it seems that VeeValidate slows down typing in input – dmitriy Jun 10 '21 at 11:01
  • Is this because of my code or vee vadalidate 4 ? – dmitriy Jun 10 '21 at 11:02
  • Normally VeeValidate shouldn't impact the "input lag". But from your code I currently can't tell why it in slower now. Also just as an tipp, you can still handle your validaten only in your `useField`. And also du not need to include the `handleSubmit` in another function, you can just return the function and use it in the template. If there would be any `error` in one of the `useField` fields, the submit would be canceled. – Mirko t. Jun 10 '21 at 11:09
  • Can you please show code example to understanding correctly – dmitriy Jun 10 '21 at 11:11
  • I use handleSubmit to trigger validation on submit button – dmitriy Jun 10 '21 at 11:12
  • 1
    Added it to the answer ;) – Mirko t. Jun 10 '21 at 11:35
  • 2
    I'm confused about the "no need to define rules for fields" comment which is in the Vee-validate hosted examples too. I've no idea what that means, but it's in both of these examples, but the second one has no "schema" I can see. It's all very confusing. – philw Jul 13 '21 at 08:23