问题
I have a table that renders based on computed properties like this. Notice how each row gets its style based on its contents. This works dandy.
computed: { rows: function () { return this.$store.getters.tableRows; }, ... }
<tr v-for="row in rows" v-bind:class="rowClass(row)">
<td v-for="(item, key, index) in row.columns" v-bind:class="classy(index)">{{item}}</td>
</tr>
I also wanted to add a collective info outside of the table, so I set up the following messaging conditional.
computed: {
finished: function () {
return this.rows.length === 5;
},
whoopsie: function () {
return this.rows[this.rows.length - 1].columns.elapsed < 0;
}, ...
}
<div v-if="finished" class="alert alert-success">Done.</div>
<div v-if="whoopsie" class="alert alert-warning">Oops.</div>
The first one works just as expected. However, the second one throws me an error that cannot read property 'columns' of undefined, which looks insane as I can clearly see the data on the screen and the length property is definitely not zero.
I tried to use debugger command to poke around there but it seems not to be invoked at that part of the code. I know the code gets executed because changing return false to return true does render a difference. And debugger seems to work at other places in the code. Weird...
I tried to store the value to a global variable as shown below. Poking in that variable from console window produces precisely the values I was expecting. I can't understand what's going on there but it's definitely some black magic.
whoopsie: function () {
window.wtf = this.rows[this.rows.length - 1];
// return true;
return false;
}, ...
- What can I do to get my hands on the values in the computed property?
- Why doesn't it do what a sane person would expect it to?
- How can debugger be invoked in there?
Edit
The store has the following getter.
tableRows: function(state) { return state.dataTable.rows; }
It's being assigned to the following object. Each row in the data has an ID and a container columns.
const rows = [];
for (let i = 0; data && i < data.length; i++)
rows.push({
id: data[i].id,
columns: {
...
elapsed: recalculate(data[i].span)
}
});
I want to bind to two computed properties that will be true if the number of rows in the table is 5 (that's finished) and if the value of elapsed on the last of the rows is negative (that's woopsie). That why I'm declaring those two (and only the first one's working).
回答1:
Error seems in this particular code to me, You can not have (item, key, index) with v-for with an array of objects, that syntax is only available with object, see the fiddle.
so You need something like following:
<tr v-for="row in rows" v-bind:class="rowClass(row)">
<td v-for="(item, index) in row.columns" v-bind:class="classy(index)">{{item}}</td>
</tr>
来源:https://stackoverflow.com/questions/41347977/cant-access-data-in-getter-when-binding-by-v-if-but-can-access-when-rendered-by