Vue JS - 渲染Multidemensional Obj

时间:2016-11-15 00:00:54

标签: vue-component vuex vue.js

我是VUE的新手,并且很难弄清楚如何渲染一个物体,我不知道它将会有多少层次。

我从web-api

返回此对象

var result = {  
               "1":{  
                  "id":"1",
                  "parent_id":"-1",
                  "name":"Master",
                  "level":1,
                  "children":{  
                     "2":{  
                        "id":"2",
                        "parent_id":"1",
                        "name":"Category A",
                        "level":2,
                        "children":{  
                           "5":{  
                              "id":"5",
                              "parent_id":"2",
                              "name":"Category D",
                              "level":3
                           },
                           "6":{  
                              "id":"6",
                              "parent_id":"2",
                              "name":"Category E",
                              "level":3,
                              "children":{  
                                 "10":{  
                                    "id":"10",
                                    "parent_id":"6",
                                    "name":"Category F",
                                    "level":4
                                 }
                              }
                           }
                        }
                     },
                     "3":{  
                        "id":"3",
                        "parent_id":"1",
                        "name":"Category B",
                        "level":2,
                        "children":{  
                           "4":{  
                              "id":"4",
                              "parent_id":"3",
                              "name":"Category C",
                              "level":3
                           }
                        }
                     }
                  }
               }
            };

我忽略了第一级并将其推送到我的商店。现在我正在寻找一种递归方式来覆盖所有父母和孩子们。 (这将是所需输出的一个例子)

<ul>
  <li>Master</li>
    <ul>
      <li>Category A</li>
      <ul>
        <li>Category D</li>
        <li>Category E</li>
        <ul>
          <li>Category F</li>
        </ul>
      </ul>
      <li>Category B</li>
      <ul>
        <li>Category C</li>
      </ul>
   </ul>
</ul>

但是我没有进一步:

<ul>
  <li>Master</li>
  <ul>
    <li>Category A</li>
    <li>Category B</li>
   </ul>
</ul>  

然后我可以继续这样下去,然后我会到达我的obj的尽头。但在实际情况下,我不知道它会走多远,这就是为什么我想要一个不关心这个问题的解决方案,直到没有更多的孩子。

我在doc中看到了一些东西,但是代码与我的代码有很大不同,以至于我无法真正理解如何应用(https://vuejs.org/v2/guide/components.html#Circular-References-Between-Components

我的初始化代码基本上就是这一切(简化):

store = function()  {
    var self = this;
    self.hierarchies  = [];
    self.subView = 'hierarchies';
    self.tree = [];
};

Vue.component('hierarchies', {
    template: '#hierarchies',
    props: ['store']
});

Vue.component('products', {
    template: '#products',
    props: ['store']
});

Vue.component('treeview', {
    template: '#treeview',
    props: ['store']
});

app = new Vue({
    el: '#content',
    data: function () {
        return {
            store: {},
            tree: {}
        }
    },
    created: function () {
        this.store = new store();
    }
});


// DO AXJAX REQUEST GET HIERARCHY'S
var response = // AJAX  {};
app.store.tree.push(response[1]);
<template id="treeview">
    <div>
        <ul v-if="store.tree.length">
            <li v-for="m in store.tree">
                {{ m.name }}
                <ul v-if="m.children">
                    <li v-for="c in m.children">
                        {{ c.name }}
                    </li>
                </ul>
                <data :tree="m"></data>
            </li>
        </ul>
    </div>
</template>

欢迎所有想法的建议:)

最佳, 巴斯蒂安

1 个答案:

答案 0 :(得分:1)

您的数据格式非常不实用,因为您无法使用v-for指令循环对象键。因此,为了使用该格式,您必须首先将其转换为数组。我正在使用计算属性,但从长远来看,更好的解决方案可能是在开始时转换数据一次,甚至更改Web服务的结果格式(如果可以的话)。

&#13;
&#13;
var result = {"1":{"id":"1","parent_id":"-1","name":"Master","level":1,"children":{"2":{"id":"2","parent_id":"1","name":"Category A","level":2,"children":{"5":{"id":"5","parent_id":"2","name":"Category D","level":3},"6":{"id":"6","parent_id":"2","name":"Category E","level":3,"children":{"10":{"id":"10","parent_id":"6","name":"Category F","level":4}}}}},"3":{"id":"3","parent_id":"1","name":"Category B","level":2,"children":{"4":{"id":"4","parent_id":"3","name":"Category C","level":3}}}}}};

Vue.component('tree-root', {
  props: ['items'],
  template: `
    <ul>
      <tree-item v-for="item in items" v-bind:item="item"></tree-item>
    </ul>
  `
});

Vue.component('tree-item', {
  props: ['item'],
  computed: {
    children: function () {
      return Object.keys(this.item.children).map(k => this.item.children[k]);
    }
  },
  template: `
    <li>
      {{item.name}}
      <tree-root v-if="item.children" v-bind:items="children"></tree-root>
    </li>
  `
});

var app = new Vue({
  el: '#app',
  data: {
    rootItem: result['1']
  }
});
&#13;
<ul id="app">
  <tree-item v-bind:item="rootItem"></tree-item>
</ul>

<script src="https://unpkg.com/vue/dist/vue.js"></script>
&#13;
&#13;
&#13;

我在这里做的是使用两个组件:tree-root负责呈现项目列表,tree-item负责呈现单个项目,最终递归呈现另一个tree-root 1}}为每个项目的孩子。

计算的children属性用于将子对象转换为子列表。

最后,为了呈现根组件,我们只将result['1']作为根元素呈现为tree-item。我们也可以使用整个tree-root渲染result,但是我们必须先将它转换为数组(就像在计算属性中一样),所以我只选择了更简单的解决方案。