我有一个这样的VueJS数据存储...
nodes: {
id: '001',
name: 'name1',
text: 'test1'
children: [
{
id: '002',
name: 'name2',
text: 'test2'
},
{
id: '003',
name: 'name3',
text: 'test3'
children: [
{
id: '0002',
name: 'name02',
text: 'test02',
children: [
{
id: '0002',
name: 'name02',
text: 'test02'
}
]
}
]
},
{
id: '004',
name: 'name4',
text: 'test4'
}
]
}
注意:儿童级别(深度)为无限制
我需要通过ID选择每个ID,然后添加/更新其同级值。
示例:“选择ID:003并添加文本2:hello'
nodes: {
id: '001',
name: 'name1',
text: 'test1'
children: [
{
id: '002',
name: 'name2',
text: 'test2'
},
{
id: '003',
name: 'name3',
text: 'test3',
text2: 'hello'
},
{
id: '004',
name: 'name4',
text: 'test4'
}
]
}
我设法使用method
进行添加/更新,该调用是:
this.$set(this.nodes, 'text2', 'hello')
我坚持按ID部分进行选择。谁能弄清楚该怎么做?
PS:我是VueJS的新手。
答案 0 :(得分:1)
如果没有订单,则可以使用:
const nodes = {
id: '001',
name: 'name1',
text: 'test1',
children: [
{
id: '002',
name: 'name2',
text: 'test2'
},
{
id: '003',
name: 'name3',
text: 'test3',
},
{
id: '004',
name: 'name4',
text: 'test4'
}
]
}
const operation = node => node.text2 = 'hello'
// recursive function applying the "operation" function on every node with the specified ID.
const applyOnId = (node, id, op) => {
if(node.id === id) {
op(node)
} else if(node.children) {
node.children.map(c => applyOnId(c, id, op))
}
}
// test
console.log('before', nodes)
applyOnId(nodes, '002', operation)
console.log('after', nodes)
请注意,它将遍历所有节点。
答案 1 :(得分:0)
几乎Nomeho的方法是仅使用此语句使用for...of
来递归地执行该语句,该语句应该比.map()
或.forEach()
(当数据变大时)有一些性能上的好处。如果不关心性能,请随意使用其他方法。
此外,还向您展示了如何使用Vue.$set
在这些节点上动态添加新道具。
const nodes = {
id: '001',
name: 'name1',
text: 'test1',
children: [
{
id: '002',
name: 'name2',
text: 'test2'
},
{
id: '003',
name: 'name3',
text: 'test3',
children: [
{
id: '0002',
name: 'name02',
text: 'test02',
children: [
{
id: '0002',
name: 'name02',
text: 'test02'
}
]
}
]
},
{
id: '004',
name: 'name4',
text: 'test4'
}
]
};
new Vue({
el: '#app',
data() {
return {
form: {
id: '003',
name: 'test2',
value: 'hello'
},
nodes,
lastChangedNode: {}
}
},
methods: {
selectNode(id, node) {
if (node.id === id) {
return node;
}
if (node.children && node.children.length) {
for (let child of node.children) {
let x;
if (x = this.selectNode(id, child)) {
return x;
}
}
}
},
addDynamicItem() {
let node = this.selectNode(this.form.id, this.nodes);
if (this.lastChangedNode = node) {
this.$set(node, this.form.name, this.form.value);
}
else {
this.lastChangedNode = {
error: 'No matching ID found'
}
}
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<input v-model="form.id" placeholder="Enter a node ID" />
<input v-model="form.name" placeholder="New property name" />
<input v-model="form.value" placeholder="New property value" />
<button @click="addDynamicItem">Add property</button>
<h3>Last changed node</h3>
<pre>{{lastChangedNode}}</pre>
<h3>All nodes</h3>
<pre>{{nodes}}</pre>
</div>