MyComponent.vue:
<BaseInput
id="name"
v-model:modelValue="user.name"
type="text"
label="Name"
name="name"
placeholder="Name"
/>
BaseInput.vue:
<template>
<input
:id="id"
:
:type="type"
:name="name"
:placeholder="placeholder"
:value="value"
@input="(event) => $emit('update:modelValue', event.target.value)"
@focus="handleInputFocus"
@keyup="handleInputKeyup"
/>
...
</template>
<script>
...
emits: ['update:modelValue'],
...
</script>
Things are kind of working here. When I type into my input, I can see that the v-model is being populated in MyComponent.vue
:
user:Reactive
name:"d"
The problem I'm seeing is the value is being replaced by whatever I type last. For example, if I entered the text "abcd" only "d" would show in the v-model.
How can I emit the entire value so that "abcd" shows?
user:Reactive
name:"abcd"
CodePudding user response:
The problem is the <input>
has no model. It only binds its value
property to a local value
ref, which likely is initially blank or null
, and that ref never gets updated.
The input
-event emits the current value of the <input>
element with the newly entered character appended to it. Since the current value is always blank in this case, the event data only contains the new character.
But it looks like the component isn't designed to modify the value
ref based on what is being emitted (e.g., filtering out characters), so it doesn't need to keep a local copy of it.
Removing the unnecessary value
ref and binding the <input>
's value
directly to modelValue
would resolve the issue:
<!-- <input :value="value"> --> ❌
<input :value="modelValue"> ✅
Side note: v-model:modelValue
can be simplified to v-model
because "modelValue"
is the default binding argument:
<BaseInput v-model:modelValue="user.name" />
<!-- is the same as: -->
<BaseInput v-model="user.name" />