在 v-if 绑定时无法访问 getter 中的数据,但在 v-for 渲染时可以访问

Posted

技术标签:

【中文标题】在 v-if 绑定时无法访问 getter 中的数据,但在 v-for 渲染时可以访问【英文标题】:Can't access data in getter when binding by v-if but can access when rendered by v-for in Vue 【发布时间】:2017-05-11 21:44:51 【问题描述】:

我有一个基于这样的计算属性呈现的表。请注意每一行如何根据其内容获取其样式。这很管用。

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>

我还想在表格之外添加一个集体信息,所以我设置了以下有条件的消息传递。

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>

第一个按预期工作。但是,第二个向我抛出了一个错误 cannot read property 'columns' of undefined,这看起来很疯狂,因为我可以清楚地看到屏幕上的数据和 length 属性绝对不为零。

我尝试使用 debugger 命令在那里四处寻找,但似乎没有在代码的那部分调用它。我知道代码会被执行,因为将 return false 更改为 return true 确实会产生差异。 debugger 似乎可以在代码的其他地方工作。奇怪...

我尝试将值存储到全局变量中,如下所示。从控制台窗口插入该变量会产生我期望的值。我不明白那里发生了什么,但这绝对是一些黑魔法。

whoopsie: function () 
  window.wtf = this.rows[this.rows.length - 1];
  // return true;
  return false;
, ...
    我可以做些什么来获取计算属性中的值? 为什么它不符合正常人的预期? 如何在其中调用调试器?

编辑

商店有以下吸气剂。

tableRows: function(state)  return state.dataTable.rows; 

它被分配给以下对象。数据中的每一行都有一个 ID 和一个容器columns

const rows = [];
for (let i = 0; data && i < data.length; i++)
rows.push(
  id: data[i].id,
  columns: 
    ...
    elapsed: recalculate(data[i].span)
  
);

我想绑定两个计算属性,如果表中的行数为 5(即 已完成)并且如果 elapsed 的值在最后一行是负数(即 woopsie)。这就是为什么我要声明这两个(并且只有第一个有效)。

【问题讨论】:

this.$store.getters.tableRows 长什么样子? @saurabh 这是一个对象数组 - id 和列。 Columns 是一个对象,其字段对应于表的内容。 [ id: xxx, columns: a:1,b:2] 我认为它不可能是问题的根源,因为我让它在控制台中给我正确的值。错误消息是该行未定义... 进一步调查后,我意识到问题可能在于 getter 为 whoopsie 返回空数组,但它在绑定到表中时返回填充的内容。在评估this.$store.getters.tableRows; 时,v-ifv-for 会产生不同的结果。 【参考方案1】:

在我看来,此特定代码中出现错误,您不能将 (item, key, index)v-for 与对象数组一起使用,该语法仅适用于 with object,请参阅 fiddle。

所以您需要以下内容:

<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>

【讨论】:

可能是我解释得不好。让我再尝试一次。表格渲染工作完美。由于我正在遍历 object 命名列,因此我需要 item,key,index。问题发生在表之外。虽然该表在rows 中的每一行都显示了一个 TR,但我还显示了基于所有行的聚合状态。如果您查看编辑,我将在那里显示更多代码。

以上是关于在 v-if 绑定时无法访问 getter 中的数据,但在 v-for 渲染时可以访问的主要内容,如果未能解决你的问题,请参考以下文章

在模板中时无法访问 Vue 商店中的 getter,因为它“不是函数”

无法在模块之外访问 Vuex getter

vue优化

Vue数据绑定失效

Vue性能优化

Vue性能优化