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?
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>