【问题标题】:VueJS select by id [data]VueJS 按 id [数据] 选择
【发布时间】:2019-07-04 02:40:53
【问题描述】:

我有一个像这样的 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: 003 并添加一个 text2: 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 的新手。

【问题讨论】:

  • "children's level (deep) is UNLIMITED" 这是否意味着除了您显示的对象之外,它还可能包含嵌套数组?如果是这样,请举例说明您的数据中的情况。如果不是,这是 stackoverflow.com/questions/7364150/… 的副本
  • @DanielBeck 不幸的是,它包含嵌套的子元素......但除了我提到的对象之外。我刚刚更新了问题的示例数组。
  • 好的,请举个例子;有很多可以结构化的方法,这会影响答案。
  • @DanielBeck 更新了! ID 也是唯一的。

标签: jquery html laravel vue.js vuejs2


【解决方案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)

注意它会遍历所有节点。

【讨论】:

  • 不确定如何使用 VueJs 实现这一点。
【解决方案2】:

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>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-04-26
    • 2011-03-28
    • 2017-03-19
    • 1970-01-01
    • 1970-01-01
    • 2016-05-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多