Как я могу заставить фильтр vuejs работать для вложенных элементов внутри массива?

В Vuejs есть поле input, в которое пользователь может ввести текст для поиска элемента.

Код работает при нормальном поиске. Как заставить фильтр работать для вложенных элементов, чтобы пользователь мог вводить поиск на основе значения элемента?

Например: если пользователь вводит Seat, массив должен быть

sales:[
  {
        id: 2,
        type: "Bike2",
        number: 3000,
           item: [
          {
            id: 400,
            name: "Seat"
          },
          {
            id: 200,
            name: "Handle"
          }
        ]
      }]

Ссылка Codepen

HTML:

<div id="container">
  <input type="text" placeholder="enter text" v-model="value">
  <p>{{ value }}</p>
  <div v-for=" sale in filteredList">
    {{sale.type}}
  </div>

  <!--     <div v-for=" sale in filteredNestedList">
      {{sale.type}}
    </div> -->
</div>

Фильтрация:

new Vue({
  el: "#container",
  data: {
    value: "",
    sales: [
      {
        id: 1,
        type: "Bike1",
        number: 2000,
        item: [
          {
            id: 100,
            name: "Wheel"
          },
          {
            id: 200,
            name: "Handle"
          }
        ]
      },
      {
        id: 2,
        type: "Bike2",
        number: 3000,
        item: [
          {
            id: 400,
            name: "Seat"
          },
          {
            id: 200,
            name: "Handle"
          }
        ]
      }
    ]
  },
   computed: {
     //Nested
    filteredNestedList() {
      return this.sales.filter((sale) => {
        return sale.item.filter((item)=>{
          return item.name.toLowerCase().includes(this.search.toLowerCase());
        })
      });
    },
     
     
    //Works for items which are not nested
    filteredList() {
      return this.sales.filter((sale) => {
        return sale.type.toLowerCase().includes(this.value.toLowerCase());
      });
    },
  },
});


person Siona Fernandes    schedule 23.02.2021    source источник


Ответы (1)


Попробуй это.

    filteredNestedList() {
      if (this.value == '') {return this.sales}
      const parents = this.sales.filter((sale) => {
        return sale.type.toLowerCase().includes(this.value.toLowerCase());
      });
      const childs = this.sales.filter((sale) => {
          return sale.item.filter((it) => {
            return it.name.toLowerCase().includes(this.value.toLowerCase())
          }).length;
      });
      console.log(childs)
      return parents.concat(childs)
    },

Мой подход заключается в разделении поиска объектов. Сначала мы ищем, какие родители имеют значение совпадения, и сохраняем его в переменной. Затем снова перейдите к поиску объекта для ребенка item. Не так сильно отличается от первого, мы также фильтруем родителей, но проверяемое значение относится к его дочернему элементу, поэтому нам нужно только знать, является ли дочерний элемент пустым или нет. Результатом этого процесса является массив отфильтрованных sales, таких же, как при первом поиске.

Последний шаг, просто объедините массив, который мы получили от этих двух фильтров.

person kusiaga    schedule 23.02.2021