logaretm / vee-validate

✅ Painless Vue forms
https://vee-validate.logaretm.com/v4
MIT License
10.79k stars 1.26k forks source link

Initial value stopped working after updating vee-validate. #4886

Closed PablitoDh closed 1 day ago

PablitoDh commented 1 week ago

What happened?

After updating vee-validate from version 4.6.2 to 4.13.2, setting the initial value in a custom input stopped working. The same issue occurred with version 4.7.x.

<script setup lang="ts">
import { toRef } from 'vue';
import { useField } from 'vee-validate';

interface InputProps {
    name: string;
    readonly?: boolean;
    type?: string;
    value?: string;
    successMessage?: string;
    placeholder?: string;
    validated?: boolean;
    label?: string;
    small?: boolean;
    hideSkeleton?: boolean;
}

const props = withDefaults(defineProps<InputProps>(), {
    type: 'text',
    value: '',
    successMessage: '',
    placeholder: ''
});

const emit = defineEmits<{
    (e: 'blur', value: string | number): void;
}>();

const modelValue = defineModel<string | number | null>({
    type: [Number, String, null],
    required: true
});

const name = toRef(props, 'name');

const { errorMessage, handleBlur, handleChange, meta } = useField(name, undefined, {
    initialValue: modelValue.value
});

function onBlur(event: Event) {
    handleBlur(event);

    emit('blur', modelValue.value);
}

function onInput(e: Event) {
    handleChange(e);
}
</script>

<template>
    <div
        class="text-input"
        :class="[{ 'has-error': !!errorMessage && validated, success: meta.valid }, { small }]"
    >
        <v-skeleton-loader
            v-if="!hideSkeleton"
            type="text"
            height="29px"
        ></v-skeleton-loader>
        <v-text-field
            v-model="modelValue"
            :name="name"
            :type="type"
            variant="outlined"
            :valid="meta.valid"
            :label="label"
            :color="meta.valid ? 'success' : ''"
            :error-messages="meta.touched ? errorMessage : ''"
            :placeholder="placeholder"
            :readonly="readonly"
            hide-details="auto"
            @input="onInput"
            @blur="onBlur"
        />
    </div>
</template>
<TextInput
     v-model="user.firstName"
     name="firstName"
     type="text"
     placeholder="First name"
/>

Reproduction steps

1. 2. 3. ...

Version

Vue.js 3.x and vee-validate 4.x

What browsers are you seeing the problem on?

Relevant log output

No response

Demo link

c

Code of Conduct

logaretm commented 1 day ago

Initial values were never meant to be reactive. This is because useField does everything defineModel does including syncing the value with the modelValue prop and using both is a bit redundant.

Initial values will only be read once at initialization/mount. We even typed the values to not accept any reactive refs to encourage people from doing that.

Can you try removing defineModel and enable { syncVModel: true } on useField to see if everything works?