First of all, I am just starting playing with VueJS, so this cannot be a VueJS version thing as suggested here
It might be a duplicate of :
- How to solve [Vue warn]: Avoid mutating a prop directly since the value will be overwritten on vue.js 2? - the difference is that I am only trying to set the values with
v-bind
, once. - Avoid mutating a prop directly since the value will be overwritten - This also looks somehow similar, but the solution didn't worked for me.
- What's the correct to modify VUE component via javascript? - this solution looks pretty much what I have in my case
- vuejs update parent data from child component
My problem starts with my Html looking like this:
<div id="app">
<div class="row">
<div class="form-group col-md-8 col-md-offset-2">
<birthday-controls
:birthDay="birthDay"
:birthMonth="birthMonth"
:birthYear="birthYear">
</birthday-controls>
</div>
</div>
</div>
and JS:
Vue.component('birthday-controls', {
template: `<div class="birthday">
<input type="text" name="year" placeholder="yyyy" v-model="birthYear" size="4" maxlength="4"/>
<input type="text" name="month" placeholder="mm" v-show="validYear" v-model="birthMonth" size="3" maxlength="2"/>
<input type="text" v-show="validYear && validMonth" name="day" placeholder="dd" v-model="birthDay" size="2" maxlength="2"/>
</div>`,
props: ['birthDay', 'birthMonth', 'birthYear'],
computed: {
validYear: function() {
return (this.birthYear > new Date().getFullYear()-100 && this.birthYear < new Date().getFullYear()-14)
},
validMonth: function() {
return (this.birthMonth > 0 && this.birthMonth <= 12)
},
validDay: function() {
return (this.birthDay > 0 && this.birthDay <=31) //I have to add more checking here for february, leap years and ....
}
}
});
new Vue({
el: '#app',
data: function() {
return {
birthDay: "",
birthMonth: "",
birthYear: ""
}
},
});
I have prepared codepen here: http://codepen.io/AngelinCalu/pen/OpXBay
However, the second answer from here: vuejs update parent data from child component makes me realise that I'm missing something
In that example it sets an this.$emit('increment')
inside one of the methods, and triggers that on specific event.
In this other example: Update a child's data component to the father component in vue.js using .vue webpack(vue2) , the answer suggest adding a watch
to emit the change.
watch: {
val() {
this.$emit('title-updated', this.val);
}
}
Now I'm even more confused! What is the right (or best) way to deal with this problem?
Note:
If I remove from the initial html
:
:birthDay="birthDay"
:birthMonth="birthMonth"
:birthYear="birthYear"
It still works as expected, but I'm still getting that Vue warn, however, if I'm following the method from here: https://stackoverflow.com/a/41901150/2012740, it stops working, but I'm getting no error.
My Updated code: https://jsfiddle.net/angelin8r/647m7vdf/
To conclude: I need the functionality from the beginning but without the [Vue warn]
This is what I got in my initial example:
[Vue warn]: 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: "birthYear"
The warning is the result of setting
v-model
to the value of your properties. The reason is because if you change birthYear, birthMonth, or birthDay outside the component, then whatever the value is currently inside the component will be immediately overwritten.Instead, capture a copy.
You did this almost exactly in your fiddle, but you did not correct your computed values.
should be