'Making v-model:value lazy
I have a simple Vue component, which comes from a 3rd party package.
The component is a text editor, and I have to provide it with a value for it to render correctly.
<SomeComponent v-model:value="text" />
<script setup>
const props = {
records: {
type: Object,
},
}
const text = computed(() => props.records.first())
</script>
Now, I want to update my database everytime the text
property is changed.
watch(text, () => {
//Post to database...
})
I don't, however, want to update the database on every keystroke - hence, I want to make the v-model
lazy. This I am trying to do like this:
<SomeComponent v-model:value.lazy="text" />
However, this doesn't work. The code inside my watch
method is being fired on every keystroke.
Solution 1:[1]
As shown in the documentation, v-model
is just some sugar syntax.
So that those are the same
<input v-model="text">
<input :value="text" @input="event => text = event.target.value">
If you want to have your component updated on the change event, you could then use something like this
<SomeComponent :value="text" @change="event => text = event.target.value" />
Or this one rather
<SomeComponent v-model.lazy="text" /> <!-- text is the getter and the setter here -->
As shown in the documentation: https://vuejs.org/guide/essentials/forms.html#lazy
If you want something even more advanced, you could look into debouncing your inputs (more work but it's kinda more clever into handling when to update the state).
Solution 2:[2]
You do not need to use
v-model:value="text"
, justv-model="text"
is enough.If you wanted the input to be lazy, without any extra functionality (like posting to DB on every change) then
v-model.lazy="text"
would be enough.When using
watch
, it doesn't matter whether your input is updated lazily or instantly. The watcher watches for each and every change, i.e: every keystroke in the case of an input.
So if you wish to make it lazy and make a call to DB on every change, then you need to this:
<SomeComponent :value="text" @change="onChange">\
<script setup>
const onChange = (event) => {
text.value = event.target.value;
// post to DB
}
</script>
If this doesn't work, then the suspect is the 3rd party package. In which case I suggest you look at the package's documentation and see if they provide a prop for the text editor to be lazy.
Solution 3:[3]
The 3rd party plugin did not allow me to omit the v-model:value
property, so I ended up using lodash' debounce method instead:
<SomeComponent v-model:value.lazy="text" />
watch(text, _.debounce(function () {
//Post to database...
}, 500));
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | kissu |
Solution 2 | |
Solution 3 | oliverbj |