Anders
Anders

Reputation: 105

Vue 2: Value prop does not update input value

So I have encountered a weird issue with my code, that I hope to get some help with.

I have a custom "Input" component where I have a normal HTML input with some styling. I have then called this component with a value and a function to call upon changes. No v-model is used as I have to do some validation on the field. However, it doesn't work. I can see that the value variable in the "Input" component changes correctly, but it does not impact the HTML input element at all, if you enter multiple values into the input field. How can this be?

InputComponent

<template>
    <label class="block text-sm flex justify-end lg:justify-start w-28 h-10">
        <span class="text-gray-800">{{ label }}</span>
        <input
            class="block text-black placeholder:text-black placeholder:opacity-40 w-14 lg:w-full rounded-lg text-center"
            :placeholder="placeholder"
            :type="type"
            :value="value"
            @input="handleInput($event.target.value)"
        />
    </label>
</template>

<script>
export default {
    props: {
        label: String,
        placeholder: String,
        type: String,
        value: String,
        size: String,
    },
    methods: {
        handleInput(value) {
            this.$emit('input', value);
        }
    },
}
</script>

Page component calling Input

<template>
<Input
    type="number"
    placeholder="0"
    size="sm"
    :value="test"
    @input="changePlannedVacationDay($event)"
/>
</template>

<script>
export default {
    data() {
        return {
            test: ""
        };
    },
    methods: {
        changePlannedVacationDay(value) {
            let localValue = value;
            const maxValue = 5;

            if (parseInt(localValue) < 0) {
                localValue = "0";
            } else if (parseInt(localValue) > maxValue) {
                localValue = maxValue.toString();
            }
            this.test = localValue;
        }
    },
</script>

Upvotes: 0

Views: 1199

Answers (1)

IVO GELOV
IVO GELOV

Reputation: 14259

You should use a computed property with getter and setter:

<template>
  <input v-model="localModel">
</template>

<script>
export default
{
  name: 'CustomInputComponent',
  props:
  {
    value:
    {
      type: String,
      default: null,
    },
  },
  computed:
  {
    localModel:
    {
      get()
      {
        return this.value;
      },
      set(val)
      {
        this.$emit('input', val);
      }
    },
  },
}
</script>

In the parent component you should use a watcher to detect value changes and act upon them.

Upvotes: 2

Related Questions