Q:

Treeview with nested inputs with VueJS

I'm trying to build a treeview component comporting inputs in order to change my source json.
The binding part seems to work fine but the hide/show action on branches is broken : 
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
As you can see, a click on the first branch ("nodeA") activate both the first and the third branches...
I think the problem comes from the click that occurs on the parent component but I can't find a way to fix my code.

A:

Your all the branches are hiding/showing together as you are using single variable show to hide and show both of those, You have to use different variable for each on node. 
It will be impractical to have as many variables as number of nodes, but you can have a hash like following:
  data: function() {
    return {
      show: {}
    };
  },

and change the toggle method to set the variable for each node by creating a key in this show hash for that node. You can use vm.$set for this which sets a property on an object. If the object is reactive, ensure the property is created as a reactive property and trigger view updates.
toggle: function(node) {
  if(this.show[node]){
    this.$set(this.show, node, false)
  } else {
    this.$set(this.show, node, true)
  }
} 

You need to do corresponding changes in HTML as well, which can be viewed in the working codepen here.

