正确输出嵌套数组

时间:2017-02-27 12:02:38

标签: javascript html vue.js vuejs2

我尝试使用组件在Vue中构建数据树。

考虑以下数据:

"data": [
{
  "id": 1,
  "name": "foo",
  "children": [
    {
      "id": 2,
      "name": "bar",
      "children": []
    },
    {
      "id": 3,
      "name": "hulu",
      "children": []
    }
  ]
},
{
  "id": 4,
  "name": "foobar",
  "children": [
    {
      "id": 5,
      "name": "foobar hulu",
      "children": []
    }
  ]
}]

现在我想输出一个像:

这样的表格

ID║名称║路径
 1║foo║/ foo
 2║bar║/ foo / bar
 3║hulu║/ foo / hulu
 4║foobar║/ foobar
 5║foobar hulu║/ foobar / foobar hulu

如果有可用的孩子,我已尝试使用“自行调用”的组件。问题是Vue.js只允许一个根元素。

我的组件:

var Element = {
    props: ['context', 'path'],
    name: 'self',
    template: `
        <tr>
            <td>{{context.id}}</td>
            <td>{{context.name}}</td>
            <td>{{path}}</td>
        </tr>
        <self v-if="context.children.length != 0" v-for="child in context.children" :context="child" :path="path + '/' + child.name"></self>
    `
};

var Tree = {
    components: {
        'element': Element
    },
    template: `
        <table v-if="elements.length != 0">
            <thead>
                <tr>
                    <th>ID</th>
                    <th>Name</th>
                    <th>Path</th>
                </tr>
            </thead>

            <element v-for="element in elements" :context="element" :path="'/' + element.name"></element>
        </table>
    `,

你会如何绕过这个问题?我已经尝试将元素模板包装在 tbody 中。这将正确计算路径并输出所有元素,但这会产生嵌套在列中的行并且看起来非常难看。

enter image description here

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

展平道路。

Vue.component("flat-tree",{
  props:["paths"],
  template: "#flat-tree-template",
  methods:{
    flatten(data, root, accumulator){
      return data.reduce((acc, val) => {
        accumulator.push({
          id: val.id,
          name: val.name,
          path: root + val.name
        });
        if (val.children)
          return this.flatten(val.children, root + val.name + "/", accumulator);
        else
          return accumulator;
      }, accumulator);
    }
  },
  computed:{
    flattened(){
      return this.flatten(this.paths, "/", []);
    }
  }
})

模板

<template id="flat-tree-template">
  <table>
    <tr v-for="path in flattened">
      <td>{{path.id}}</td>
      <td>{{path.name}}</td>
      <td>{{path.path}}</td>
    </tr>
  </table>
</template>

Working example