Here is a simplified version of my code:
Vue.component('entry', {
template: '\
<div>\
<label>Name: <input type="text" v-model="entry.name"></label>\
</div>\
',
props: ['entry']
});
Vue.component('entries', {
template: '\
<div>\
<entry v-for="entry in entries" :entry="entry"></entry>\
<pre>{{ combined }}</pre>\
</div>\
',
props: ['entries'],
computed: {
combined: function() {
combined = [];
this.entries.forEach(function(entry) {
combined.push(entry.name);
});
return combined.join("\n");
}
}
});
var entries = [
{name: "Entry 1"},
{name: "Entry 2"},
{name: "Entry 3"}
];
JSFiddle here: https://jsfiddle.net/msw3Lx98/3/
The top-level component (entries) takes a list of objects, and creates a subcomponent (entry) for each one. The subcomponent binds the entry data to an input.
When the user modifies the data by typing into one of the inputs, the top-level component needs to push the updated value of combined to a separate bit of code.
My understanding of the watcher model is that if the top-level component watches entries it can detect when things are added to or removed from the list, but not when data within an entry changes.
However, the top-level component clearly does see this sort of change in some way, because as the user types into an input the value of combined gets updated.
Is there a "correct" way to detect this sort of change?
Here are a few options that I've explored:
- Define an
updatedmethod on the subcomponent. In that method emit a custom event, and handle this event in the parent. This is fairly awkward and I don't think it will scale very well. - Define a
beforeUpdatemethod on the parent -- this (but notupdated) runs whenever there's a change in a subcomponent. I'm not sure why, and it doesn't smell right to me. - In the top-level component, watch the
combinedproperty. I'm sort of surprised this works, but it does. This seems the most straightforward option, but it's not obvious from the Vue docs that computed properties are intended to be watchable, so I'm reluctant to rely on this.
