Javascript 带有VueJS的嵌套输入的Treeview
我正试图构建一个treeview组件来编写输入,以便更改我的源json 绑定部分似乎工作正常,但分支上的隐藏/显示操作已中断: HTML:Javascript 带有VueJS的嵌套输入的Treeview,javascript,vue-component,vuejs2,vue.js,Javascript,Vue Component,Vuejs2,Vue.js,我正试图构建一个treeview组件来编写输入,以便更改我的源json 绑定部分似乎工作正常,但分支上的隐藏/显示操作已中断: HTML: <div id="app"> <tree :data="json" :link="json"></tree> <p>Outside component :</p> <pre>{{json}}</pre> </div> 外部组件: let json
<div id="app">
<tree :data="json" :link="json"></tree>
<p>Outside component :</p>
<pre>{{json}}</pre>
</div>
外部组件:
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
}
});
{{json}}
JS:
let json={
诺迪亚:{
nodeA1:“valueA1”,
节点A2:“值A2”
},
nodeB:“valueB”,
诺代克:{
节点1:“值C1”,
节点2:“值C2”
}
};
Vue.component('树'{
名称:“treeview”,
道具:[
"数据",,
“链接”
],
模板:`
-
{{key}}
`,
数据:函数(){
返回{
节目:假
};
},
方法:{
isLeaf:函数(节点){
返回节点的类型!=“对象”;
},
切换:函数(){
this.show=!this.show;
}
}
});
新Vue({
el:“#应用程序”,
数据:{
json:json
}
});
如您所见,单击第一个分支(“节点”)即可激活第一个和第三个分支
我认为问题来自于在父组件上发生的单击,但我找不到修复代码的方法。发生这种情况是因为您将所有元素绑定到同一个参数 要单独切换每个元素的可见性,需要将元素状态存储在它自己的位置,如对象的字段或数组
但我想更好的解决方案是通过单击切换目标元素上的类,并通过类通过css控制可见性。您的所有分支都隐藏/显示在一起,因为您使用单个变量
show
要隐藏和显示这两个分支,您必须为每个节点使用不同的变量
将变量数量设置为节点数量是不切实际的,但可以使用如下哈希:
toggle: function(node) {
if(this.show[node]){
this.$set(this.show, node, false)
} else {
this.$set(this.show, node, true)
}
}
并通过在该节点的show
哈希中创建一个键,更改切换方法以设置每个节点的变量。您可以使用设置对象属性的。如果对象是被动的,请确保将该属性创建为被动属性,并触发视图更新
您还需要在HTML中进行相应的更改,这些更改可以在工作代码笔中查看。您可能需要为每个节点设置一个
show
字段来分别切换其可见性,在我的中,我使用的数据结构如下:
<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;
}
}
}
此解决方案是Functional,但需要对源JSON进行重大更改,这是不需要的。感谢您的建议。简单但高效:)此外,有没有更好的解决方案将嵌套输入与源JSON绑定,而不是将链接作为道具传递?@Pourpre如果您询问道具的替代方案,您可以使用vuex,如果它符合您的要求,您可以查看或我的答案或。
<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;
}
}
}