I'm trying to use a data coming from a prop with v-model, the following code works, but with a warning.
<template>
<div>
<b-form-input v-model="value" @change="postPost()"></b-form-input>
</div>
</template>
<script>
import axios from 'axios';
export default {
props: {
value: String
},
methods: {
postPost() {
axios.put('/trajectory/inclination', {
body: this.value
})
.then(response => {
})
.catch(e => {
this.errors.push(e)
})
}
}
}
</script>
The warning says:
"Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "value"
So I changed and now I'm using a data as the warning says.
<template>
<div>
<b-form-input v-model="_value" @change="postPost()"></b-form-input>
</div>
</template>
<script>
import axios from 'axios';
export default {
props: {
value: String
},
data() {
return {
_value: this.value
}
},
methods: {
postPost() {
axios.put('/trajectory/inclination', {
body: this._value
})
.then(response => {
})
.catch(e => {
this.errors.push(e)
})
}
}
}
So now the code it's not working and the warning says:
"Property or method "_value" is not defined on the instance but referenced during render. Make sure to declare reactive data properties in the data option"
Any idea how to fix the first code to suppress the warning? (or some idea on how to fix the second code?)
Obs.: b-form-input it's not my componente, this is the Textual Input from Boostrap-Vue (Doc for b-form-input)
Bert addresses your direct issue, but I think you should also know that your approach is a bit off. Since ultimately you are sending the new value to
postPost
, you don't really need to modify your local copy. Use theevent
object that is sent to thechange
handler to get the current value from the input.Instead of
v-model
, just use:value
, and don't include the invocation parentheses when specifying thechange
handler._ prefixed properties are reserved for Vue's internal properties.
Try changing _value to something that doesn't start with an underscore.
For those still coming through to this, the official Vue docs shows how to use
v-model
on a custom component: https://vuejs.org/v2/guide/components.html#Using-v-model-on-ComponentsTL;DR:
You simply need to have a specifically named
value
prop, and emit aninput
event which thev-model
when you instantiate the component maps for you.More info on how this works on the link above.
Answer is from https://github.com/vuejs/vue/issues/7434
Props are read-only, but you are trying to change its value with v-model. In this case, if you change the input value, the prop is not modified and the value is restored on the next update.
Use a data property or a computed setter instead:
https://vuejs.org/v2/guide/computed.html#Computed-Setter
One general workaround is to introduce a data-variable and watch the props to update-variable. This is quite subtle and so easy to get wrong so here's an example with a Vuetify modal using
v-model
(the same technique, in theory, should work with<input>
and others):