When binding a vee-validate field to a v-autocomplete component, the input displays [object Object] whenever an option is selected. On blurring the input, the correct value is displayed, the issue only occurs when the focus is on the input field.
The v-autocomplete component is configured with return-object
, which is necessary in this specific use case because there may be duplicate titles with different ID's, so the ID needs to remain associated with the title at all times.
Is there a modification that can be made here so that the title of the item is rendered correctly while the input is focused?
<script setup>
import { ref } from 'vue';
import { useForm, Form, Field } from 'vee-validate';
import * as yup from 'yup';
const schema = yup.object({
tags: yup
.object()
.shape({
// make C invalid to demo that validation works as expected
title: yup.string().oneOf(['A', 'B']),
value: yup.string().oneOf(['id-a', 'id-b']),
})
.required()
.label('Tag'),
});
const tags = [
{ title: 'A', value: 'id-a' },
{ title: 'B', value: 'id-b' },
{ title: 'C', value: 'id-c' },
];
const tag = ref('');
</script>
<template>
<Form :validation-schema="schema">
<Field v-model="tag" name="tags" v-slot="{ field, errors, value }">
<v-autocomplete
id="tags"
:items="tags"
v-bind="field"
clearable
return-object
:errorMessages="errors"
placeholder="Select a tag"
></v-autocomplete>
</Field>
</Form>
</template>
Simple reproduction here: https://stackblitz.com/edit/vee-validate-v4-vuetify-5o9oev?file=src%2FApp.vue
I expect that when selecting a value from the dropdown, the title of that value is displayed in the input box. However this is only true after blurring the input, while it is focused it displays [object Object]
instead
The field
slot prop contains a value
property, which through v-bind ends up on the input. Remove it from the slot props to get rid of the issue:
<Field v-slot="{field: {value, ...fieldWithoutValue}, errors}" ...>
<v-autocomplete
v-bind="fieldWithoutValue"
...
The expression {field: {value, ...fieldWithoutValue}
destructures value
into its own variable and puts all other properties into a new object, accessible through a new variable fieldWithoutValue
(you can also call it field
again).
Here is the updated stackblitz