如何使用Vue在JSON中以相同级别处理对象和数组?

时间:2019-07-17 15:32:23

标签: json vue.js

我有一个要从中提取的json文档来填充表格以及工作表中的其他几个项目。在文档的同一“级别”,我有对象和数组。我不确定如何管理在Vue中显示数组的子级和对象的子级。

我尝试使用各种if语句分别显示对象的子级和数组的子级,但是没有运气。

由于隐私原因,我无法显示实际的代码,但这是我正在寻找的用于解决此问题的数据的过于简单的示例:

"Pairs": [
        {
            "Value": {
                "Id": "123"
            },
            "Children": [
                "Id": "111",
                "String": {
                    "Value": "999",
                    "Children": [
                        {
                            "Key": "555"
                        },
                        {
                            "Key": "444"
                        },
                    ]
                }
            ]   
        },
        {
            "Value": {
                "Id": "456"
            },
            "Children": [
                "Id": "178",
                "Strings": [
                    {
                        "Value": "845",
                        "Children": [
                            {
                                "Key": "079"
                            },
                            {
                                "Key": "106"
                            }
                        ]
                    },
                        "Value": "578",
                        "Children": [
                            {
                                "Key": "279"
                            },
                            {
                                "Key": "745"
                            }
                        ]
                ]
            ]
        }
]

然后这是我在Vue前端的桌子

<table>
    <template v-for="Pair in Pairs">
        <template v-for="Child in Pair.Children">
            <template v-for="String in Child.Strings"> --- PROBLEM HERE
                <tr v-for="Child in String.Children">
                    <td>{{Child.Key}}</td>
                </tr>
            </template>
        </template>
    </template>
</table>  

从上面的示例中可以看到,Pairs数组中的第一个对象有一个名为“ String”的对象,第二个对象有一个名为“ Strings”的数组。如您所料,尝试访问Vue文档中的对象String或数组Strings时,出现未定义的错误。我很困。

1 个答案:

答案 0 :(得分:2)

通常,将使用计算属性将数据转换成更易于在模板中使用的形式,从而完成类似的操作。像这样:

const Pairs = [
  {
    "Value": {
      "Id": "123"
    },
    "Children": [{
      "Id": "111",
      "String": {
        "Value": "999",
        "Children": [
          {
            "Key": "555"
          },
          {
            "Key": "444"
          }
        ]
      }
    }]
  },
  {
    "Value": {
      "Id": "456"
    },
    "Children": [{
      "Id": "178",
      "Strings": [
        {
          "Value": "845",
          "Children": [
            {
              "Key": "079"
            },
            {
              "Key": "106"
            }
          ]
        },
        {
          "Value": "578",
          "Children": [
            {
              "Key": "279"
            },
            {
              "Key": "745"
            }
          ]
        }
      ]
    }]
  }
]

new Vue({
  el: '#app',
  
  data () {
    return { Pairs }
  },
  
  computed: {
    rows () {
      const pairs = this.Pairs
      const rows = []
      
      for (const pair of pairs) {
        for (const child of pair.Children) {
          const strings = child.Strings || [child.String]
          
          for (const string of strings) {
            const row = []
            rows.push(row)

            for (const innerChild of string.Children) {
              row.push(innerChild.Key)
            }
          }
        }
      }
      
      return rows
    }
  }
})
td {
  border: 1px solid #000;
}
<script src="https://unpkg.com/vue@2.6.10/dist/vue.js"></script>
<div id="app">
  <table>
    <tr v-for="row in rows">
      <td v-for="entry in row">{{ entry }}</td>
    </tr>
  </table>
</div>

我不得不在样本数据中添加一些额外的花括号,因为原始格式无效。

只需对模板进行少量更改即可实现此目的,但通常应鼓励模板保持简单,并将任何复杂的内容放入组件的JS部分。

<template v-for="String in Child.Strings || [Child.String]">

上面的代码假定StringsString中的一个将一直存在。如果它们都可能丢失,那么您可以改用这样的方法:

<template v-for="String in [].concat(Child.Strings || Child.String || [])">

或将逻辑移入方法:

<template v-for="String in getStrings(Child)">
methods: {
   getStrings(Child) {
      // Pull out Strings or [String] as appropriate
   }
}