VueJS按ID选择[数据]

时间:2019-02-10 12:32:17

标签: jquery html laravel vue.js vuejs2

我有一个这样的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的新手。

2 个答案:

答案 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>