2017-01-12 51 views
1

我想構建一個樹視圖組件comporting輸入以改變我的源json。樹視圖嵌套輸入與VueJS

結合部似乎很好地工作,但在樹枝隱藏/顯示動作被打破:

HTML:

<div id="app"> 
    <tree :data="json" :link="json"></tree> 

    <p>Outside component :</p> 
    <pre>{{json}}</pre> 
</div> 

JS:

let json = { 
    nodeA: { 
    nodeA1 : "valueA1", 
    nodeA2 : "valueA2" 
    }, 
    nodeB: "valueB", 
    nodeC: { 
    nodeC1 : "valueC1", 
    nodeC2 : "valueC2" 
    } 
}; 

Vue.component('tree', { 
    name: 'treeview', 
    props: [ 
    'data', 
    'link' 
    ], 
    template: `<ul> 
     <li v-for="(val, key) in data"> 
      <input type="text" v-if="isLeaf(val)" v-model=link[key]> 
      <span @click="toggle">{{key}}</span> 
      <tree v-if="!isLeaf(val)" v-show="show" :data="val" :link="link[key]"> 
      </tree> 
     </li> 
    </ul>`, 
    data: function() { 
    return { 
     show: false 
    }; 
    }, 
    methods: { 
    isLeaf: function(node) { 
     return typeof node != 'object'; 
    }, 
    toggle: function() { 
     this.show = !this.show; 
    } 
    } 
}); 

new Vue({ 
    el: '#app', 
    data: { 
    json: json 
    } 
}); 

https://codepen.io/anon/pen/EZKBwL

由於你可以看到,點擊第一個分支(「nodeA」)激活這兩個第一個和第三個分支...

我認爲問題來自父組件上發生的點擊,但我找不到修復我的代碼的方法。

回答

0

當您使用單個變量show來隱藏和顯示這兩者時,您的所有分支一起隱藏/顯示,您必須爲每個節點使用不同的變量。

這將是不切實際的,有儘可能多的變量節點的數量,但你可以有一個像下面的哈希:

data: function() { 
    return { 
     show: {} 
    }; 
    }, 

,改變切換方法,通過創建密鑰設置每個節點的變量在該節點的這個show散列中。您可以使用vm.$set來爲此設置對象的屬性。如果對象處於被動狀態,請確保將該屬性創建爲反應屬性並觸發視圖更新。

你需要做的HTML相應的變化,以及,它可以在工作codepen here觀看。

+0

簡單但高效:)另外,是th使用源JSON綁定嵌套輸入的一個更好的解決方案,而不是將鏈接作爲通道傳遞? – Pourpre

+0

@Pourpre如果你問道具的替代品,你可以使用vuex如果它適合你的要求,你可以看[文檔](https://vuex.vuejs.org/en/)或我的回答[這裏]( HTTP://計算器。com/a/40830610/1610034)或[here](http://stackoverflow.com/questions/40953496/vue-shared-data-between-different-pages/40955110#40955110)。 – Saurabh

0

發生這種情況是因爲您將所有元素綁定在相同的參數上。

要爲每個元素單獨切換可見性,您需要將元素狀態存儲在自己的位置,如對象的字段或數組。

但我想更好的解決方案是切換目標元素上的類通過單擊和通過類的css控制可見性。

-1

您可能需要一個show場爲每個節點分別切換自己的知名度,在我的improved example,我使用的數據結構是這樣的:

{ 
    "nodeA": { 
     "value": { 
      "nodeA1": { 
       "value": "valueA1", 
       "show": false 
      }, 
      "nodeA2": { 
       "value": "valueA2", 
       "show": false 
      } 
     }, 
     "show": true 
    }, 
    "nodeB": { 
     "value": "valueB", 
     "show": true 
    } 
} 

我的模板:

<ul> 
    <li v-for="(val, key) in data" v-show='val.show'> 
     <input type="text" v-if="isLeaf(val)" v-model='link[key].value'> 
     <span @click="toggle(val.value)">{{key}}</span> 
     <tree v-if="!isLeaf(val)" :data="val.value" :link="val.value"> 
     </tree> 
    </li> 
</ul> 

方法:

{ 
    isLeaf: function(node) { 
     return typeof node.value != 'object'; 
    }, 
    toggle: function(value) { 
     for (const nodeName in value) { 
      value[nodeName].show = !value[nodeName].show; 
     } 
    } 
} 
+1

此解決方案是功能性的,但需要對源JSON進行重大更改,這是不需要的。感謝您的提議。 – Pourpre