tl;dr: in vue2, you need to use the .sync modifier.
Create a local copy of the content prop in the parent's data (see reason here).
var parent = {
...
data() {
return {
localContent: this.content // creating a local copy, so we can mutate and react to it
}
}
};
Now, pass that localContent to the child, not content. And pass it using .sync so it can be updated:
var parent = {
template: '<div><child :content.sync="localContent"></child></div>',
... // ^^^^^^^^^^^^^^^^^^^^-- changed here
Now, in the child, don't assign to this.content.value, emit an update event instead:
var child = {
...
change() {
this.$emit('update:content', {value: "Value changed !"})
}
}
};
This event, with the new value, will be picked up by the parent and will update its localContent which also will, in consequence, update the child's content prop.
Final running code below.
var parent = {
template: '<div><child :content.sync="localContent"></child><br>At parent: {{ localContent }}</div>',
props: ['content'],
data() {
return {
localContent: this.content
}
}
};
var child = {
template: '<div>At child: {{ content.value }}<button @click="change">change me</button></div>',
props: ['content'],
methods: {
change() {
this.$emit('update:content', {value: "Value changed !"})
}
}
};
Vue.component('child', child);
Vue.component('parent', parent);
new Vue({
el: '#app'
});
<script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
<div id="app">
<parent :content="{value:'hello parent'}"></parent>
</div>