【问题标题】:Filter on nested (recursive) data ( Vue 2 )过滤嵌套(递归)数据(Vue 2)
【发布时间】:2019-07-27 01:50:28
【问题描述】:

这是我的 JSON 数据示例:

"data":[  
  {  
     "id":01,
     "name":"test",
     "parent_id":null,
     "children":[  
        {  
           "id":15,
           "name":"subChild",
           "parent_id":21,
           "children":[  
              {  
                 "id":148,
                 "name":"subSubChild",
                 "parent_id":22,
                 "children":[  
                        ....
                 ]
              }
           ]
        }
     ]
  },

我想逐级过滤此级别。我做了这个方法:

computed: {
      filteredData: function () {
        let filterData = this.filter.toLowerCase()
        return _.pickBy(this.data, (value, key) => {
          return _.startsWith(value.name.toLowerCase(), filterData)
        })
      },

这项工作仅适用于第一个“级别”,我尝试了几种解决方案,但没有一个适用于儿童。

所以,我希望能够按多个级别进行过滤。

如果你有想法! 谢谢

【问题讨论】:

  • 预期输出是什么? filterDataname 的对象?
  • 是的。有关更多详细信息: - 类别 1 - 子类别 1-1 - 类别 2 - 子类别 2-1 - 子类别 2-2 - 类别 3 ..... 如果我使用“子类别 2-2”的过滤器,我想仅查看“subCategory 2-2”和父“Category 2”。我希望我让自己明白!谢谢你
  • @Lolo 我下面的回答有意义吗?如果我遗漏了什么,请告诉我,以便我们解决。
  • @jom 当然!我在下面回答了你!再次感谢!!!

标签: vue.js filter nested lodash children


【解决方案1】:

递归函数可以用于此特定目的。

尝试以下方法,为了更好地查看,请单击下方 Run code sn-p 按钮旁边的 Full page 链接。

new Vue({
  el: '#app',

  data() {
    return {
      filter: '',
      maintainStructure: false,
      data: [{
        "id": 01,
        "name": "test",
        "parent_id": null,
        "children": [{
          "id": 15,
          "name": "subChild",
          "parent_id": 21,
          "children": [
            {
              "id": 148,
              "name": "subSubChild",
              "parent_id": 22,
              "children": []
            }, 
            {
              "id": 150,
              "name": "subSubChild3",
              "parent_id": 24,
              "children": []
            }
          ]
        }]
      }]
    }
  },

  methods: {
    $_find(items, predicate) {
      let matches = [];

      for (let item of items) {
        if (predicate(item)) {
          matches.push(item);
        } 
        else if (item.children.length) {
          let subMatches = this.$_find(item.children, predicate);
          
          if (subMatches.length) {
            if (this.maintainStructure) {
              matches.push({
                ...item,
                children: subMatches
              });
            }
            else {
              matches.push(subMatches);
            }
          }
        }
      }

      return matches;
    },

    filterBy(item) {
      return item.name.toLowerCase().startsWith(this.filter.toLowerCase());
    }
  },

  computed: {
    filteredData() {
      return this.$_find(this.data, this.filterBy);
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">
  <div>
    <label>Filter by <code>item.name</code>:</label>
    <input v-model.trim="filter" placeholder="e.g. subsub" />
  </div>
  
  <div>
    <label>
      <input type="checkbox" v-model="maintainStructure" /> Maintain structure
    </label>
  </div>
  
  <hr />
  
  <pre>{{filteredData}}</pre>
</div>

请注意,我在函数前面加上$_ 以将其标记为私有 函数(如this Style Guide 中所建议的那样),因为我们不会在其他任何地方调用它。

【讨论】:

  • 您好,非常感谢您的帮助!我被困了几天......这很有效。祝你有美好的一天!
  • @Lolo 没问题。很高兴我们把它整理出来。 :)
猜你喜欢
  • 2020-02-25
  • 1970-01-01
  • 1970-01-01
  • 2020-07-28
  • 2019-09-15
  • 1970-01-01
  • 2018-01-26
  • 2023-04-02
  • 2017-08-10
相关资源
最近更新 更多