2017-02-27 5 views
1

コンポーネントを使用して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║バー║/foo/bar
3║hulu║/ foo/hulu
4 foobar║/ foobar
5 foobar hulu║/ foo bar/foobar hulu

子どもがいる場合は「自分自身を呼び出す」コンポーネントを使用しようとしました。問題は、Vue.jsが1つのルート要素しか許可しないことです。

マイコンポーネント:

あなたはこの問題を回避する方法を
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

パスを平坦化します。

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

+0

素晴らしい!残念ながらあなたのコードは動作しませんが、私はそれを自分で考え出しました。なぜデータを出力するために計算されたプロパティを使用していますか? v-for = "flatten(パス、/ /、[])"は同じではありませんか? – Qobus

+0

@ Qobus私はcodepenで少し遊んでいたので、悪い状態のときにリンクをクリックした可能性があります。謝罪します。それは今働いているはずです。私は平坦化されたパスが元のパスから派生しているため、計算されたプロパティを使用しています。計算を使用することにより、元のパスが変更された場合、平坦化されたパスが再計算され、新しい状態が反映されます。 – Bert

+0

@ Qobusは一般的には、少なくとも私にとってはきれいに見えます。あなたは正しいですが、v-for = "flattenのパス(パス、 '/'、[])はほぼ同じことを成し遂げます。 – Bert

関連する問題