如何使用"Object.keys"函数列出vue.js中firebase子节点的长度时出错?

Joa*_*cho 1 javascript firebase vue.js firebase-realtime-database

想象一下一个Vue.js应用程序,其中firebase中的数据结构将发展成如下所示:

item: {
  name: itemName,
  childOne: {
    subChildA: true,
    subChildB: true
  },
  childTwo: {
    subChildA: true,
    subChildB: true
  }
}
Run Code Online (Sandbox Code Playgroud)

现在我有一个组件,我需要列出子节点的长度(这些子节点将只在以后添加).我的第一个想法是简单地这样做,但这个策略不起作用:

<tbody>
  <tr v-for="item in items" >
     <td>
        {{item.childOne.length - item.childTwo.length}}
     </td>
   </tr>
</tbody>
Run Code Online (Sandbox Code Playgroud)

所以我也得到了这样的长度:

<tbody>
   <tr v-for="item in items" >
      <td>
         {{Object.keys(item.childOne).length - Object.keys(item.childTwo).length}}
      </td>
    </tr>
</tbody>
Run Code Online (Sandbox Code Playgroud)

正如我所说,我需要在创建项目的子项之前呈现该组件...这些子节点稍后通过Google Cloud Function有条件地创建,因此我不可避免地从这个简单的结构开始:

item: {
  name: itemName,
}
Run Code Online (Sandbox Code Playgroud)

...但在此阶段我收到一条错误消息:

TypeError:无法在Function.keys()中将undefined或null转换为对象

我在想如果我使用第一个策略,vue.js足够智能,可以避免这个错误渲染组件,如果没有子节点则不显示任何内容,但它无法获得长度.

当我添加子项时,第二种策略可以正常工作,但它无法处理数据的初始缺失,甚至无法呈现视图.

当子节点还没有时,是否有使用第二种策略来防止此错误?

Ell*_* B. 5

您可以使用双管道运算符为其中item.childOneitem.childTwo未定义的实例提供默认空对象.

改变这个:

{{Object.keys(item.childOne).length - Object.keys(item.childTwo).length}}
Run Code Online (Sandbox Code Playgroud)

对此:

{{Object.keys(item.childOne || {}).length - Object.keys(item.childTwo || {}).length}}
Run Code Online (Sandbox Code Playgroud)

小规模的例子:

var test = {};
console.log(Object.keys(test.childOne || {}).length);
Run Code Online (Sandbox Code Playgroud)

但是,您应该注意Vue无法检测属性添加或删除.根据文档:

由于Vue在实例初始化期间执行getter/setter转换过程,因此数据对象中必须存在一个属性,以便Vue转换它并使其具有反应性.

根据您的确切用例,您可能需要childOne在初始化期间定义或将其转换为数组,以便您可以利用Vue 观察到的数组变异方法.