My application is a cut-down spreadsheet built in Vue with Vuex. The key components are TableCollection
, Table
and Row
. The TableCollection
has an array with multiple Table
objects. Each Table
has an array with multiple Row
objects.
The Row
component has a property named calculatedField
. This simply combines two fields in the row to produce a third field. My options are to implement calculatedField
as a computed property, local to the Row
component, or as a getter in the Vuex store.
The Table
component requires a subTotal
value, which is calculated by adding the calculatedField
for all rows in the table. As you can see, the subTotal
calculation is dependent on the calculatedField
calculation.
If I implement calculatedField
as a local computed property of Row
, it is cached. The problem is however that I can't seem to access the calculated field from a Table
parent. I tried the following in Table
:
computed : {
subTotal : function () {
let total = 0;
this.table.rows.forEach(function (row) {
total += row.calculatedField;
});
return total;
}
}
The result was NaN.
One solution would be to duplicate the logic from calculatedField
in the computed property of Table
, but that's not DRY.
The other alternative would be to implement both subTotal
and calculatedField
as getters in the store, however this would mean passing arguments to the gettter (tableId
, rowId
, or both), and so the results would not be cached. This seems really inefficient.
The final possibility is that I implement my calculatedField
logic in a global helper or mixin. This would avoid code duplication and getter inefficiency, but doesn't feel quite right - the code relates specifically to Table
and Row
, and would ideally be kept there.
Are there other solutions I have overlooked? What is the ideal 'Vue-way'?
If performance is an issue and caching is important right now, you might want to implement caching on the
Table
component.In the Row component, emit the new value so the parent component can cache it.
In the Table component, handle the event and cache the new values.
When a
Row
's data is updated, it triggers a change event with the new calculated value and the parentTable
keeps track of the calculated values, using this cache to get the subtotal.You can see in the following example that the computed properties are hit once, then on row changes (click the Rand button), only the relevant computed properties are refreshed.