2016-11-15 54 views
0

我是VUE的新手,很難搞清楚如何渲染一個Object,我不知道它會去多少級別。Vue JS - Rendering Multidemensional Obj

我得到這個對象從網絡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>

而且offcourse我繼續這樣下去,然後我會達到我的obj的結尾。但在實際情況下,我不知道它會走多深,這就是爲什麼我想要一個不關心這個問題的解決方案,並且直到沒有更多的孩子。

我看到的文檔的一個小東西,但這些代碼是從我如此不同,我無法真正瞭解如何應用(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

您的數據是在一個相當不切實際的格式,因爲你可以在使用v-for指令對象鍵不循環。所以爲了使用這種格式,你必須首先將它轉換成數組。我爲此使用了一個計算屬性,但長期運行的更好解決方案可能是一開始就轉換一次數據,甚至更改Web服務的結果格式(如果可以的話)。

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'] 
 
    } 
 
});
<ul id="app"> 
 
    <tree-item v-bind:item="rootItem"></tree-item> 
 
</ul> 
 

 
<script src="https://unpkg.com/vue/dist/vue.js"></script>

什麼我在這裏做的是使用兩個組件:tree-root負責渲染的項目清單,並tree-item這是負責呈現單個項目,最終遞歸渲染另一tree-root爲每個項目的孩子。

計算出的children屬性用於將子對象轉換爲子對象列表。

最後,爲了渲染根分量,我們只渲染作爲根元素的result['1']作爲tree-item。我們也可以渲染一個tree-root而不是整個result,但是之後我們必須先將它轉換爲一個數組(就像在計算屬性中一樣),所以我選擇了更簡單的解決方案。

+0

謝謝打了一個非常廣泛和解釋得很好的答覆。根據你的樣品,我得到它的工作!真棒,這使我的一天:-) – Bastian

+0

@Bastian很高興我能幫助!請記住注意有用的答案並最終[接受解決您問題的答案](http://meta.stackexchange.com/a/5235/141542)將問題標記爲已解決。 – poke