我正在尝试构建一个使用输入的树视图组件来更改我的源json。
绑定部分似乎工作正常,但分支上的隐藏/显示操作被破坏:
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
如您所见,点击第一个分支(&#34; nodeA&#34;)激活第一个和第三个分支......
我认为问题来自于父组件上发生的点击,但我无法找到修复代码的方法。
答案 0 :(得分:0)
之所以发生这种情况,是因为您将所有元素绑定在同一个参数上。
要为每个元素单独切换可见性,以便将元素状态存储在自己的位置,如对象的字段或数组。
但我想更好的解决方案是通过点击并通过css控制css的可见性来切换目标元素上的类。
答案 1 :(得分:0)
当您使用单个变量show
来隐藏和显示这两个分支时,您的所有分支都隐藏/显示在一起。您必须为每个节点使用不同的变量。
拥有与节点数一样多的变量是不切实际的,但是你可以有如下的散列:
data: function() {
return {
show: {}
};
},
并更改toggle方法,通过在该节点的此show
哈希中创建一个键来为每个节点设置变量。您可以使用vm.$set来为设置对象的属性。如果对象是被动的,请确保将该属性创建为被动属性并触发视图更新。
toggle: function(node) {
if(this.show[node]){
this.$set(this.show, node, false)
} else {
this.$set(this.show, node, true)
}
}
您还需要对HTML进行相应的更改,这可以在工作代码集here中查看。
答案 2 :(得分:-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;
}
}
}