如何使用 Vue JS 根据多个 select 下拉列表过滤项目?

How to filter items based on multiple select dropdown with Vue JS?

我正在学习 vue.js,我正在尝试使用多个下拉菜单和按钮搜索进行案例研究搜索。我需要找到一个过滤功能,该功能将根据使用触发按钮搜索从多个下拉列表中进行的选择来过滤对象列表。

我有下面编写的代码,但是这个过滤器是实时工作的。选择其中一个下拉菜单后,它将显示搜索结果。但是我想要的是选择几个下拉菜单后出现搜索结果,必须点击搜索按钮,然后才会出现结果。

我一直在寻找一些参考资料并尝试过,但仍然没有得到我想要的结果。

new Vue({
  el: '#app',
  data: {
    selectedType: '',
    selectedCountry: '',
    selectedYear: '',
    items: [
      {
        name: 'Nolan',
        type: 'mercedes',
        year: '2020',
        country: 'england'
      },
      {
        name: 'Edgar',
        type: 'bmw',
        year: '2020',
        country:'belgium'
      },
      {
        name: 'John',
        type: 'bmw',
        year: '2019',
        country: 'england'
      },
      {
        name: 'Axel',
        type: 'mercedes',
        year: '2020',
        country: 'england'
      }
    ]
  },
  computed: {
    searchItem: function () {
      let filterType= this.selectedType,
          filterCountry = this.selectedCountry,
          filterYear = this.selectedYear
      
      return this.items.filter(function(item){
        let filtered = true
        if(filterType && filterType.length > 0){
          filtered = item.type == filterType
        }
        if(filtered){
          if(filterCountry && filterCountry.length > 0){
            filtered = item.country == filterCountry
          }
        }
        if(filtered){
          if(filterYear && filterYear.length > 0){
            filtered = item.year == filterYear
          }
        }
        return filtered
      })
    }
  }
})
.list-item{
  margin-top:50px;
}

.card{
  box-shadow:0px 10px 16px rgba(0,0,0,0.16);
  width:400px;
  padding:20px 30px;
  margin-bottom:30px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.1/vue.js"></script>

<div id="app">
  <select v-model="selectedType">
    <option value="mercedes">Mercedes</option>
    <option value="bmw">BMW</option>
  </select>
  
  <select v-model="selectedCountry">
    <option value="belgium">Belgium</option>
    <option value="england">England</option>
  </select>
  
  <select v-model="selectedYear">
    <option value="2019">2019</option>
    <option value="2020">2020</option>
  </select>
  
  <button>Search</button>
  
  <div class="list-item" v-for="item in searchItem">
    <div class="card">
      <p>Name: {{ item.name }}</p>
      <p>Car: {{ item.type }}</p>
      <p>Year: {{ item.year }}</p>
      <p>Country: {{ item.country }}</p>
    </div>
  </div>
</div>

考虑定义过滤方法,而不是使用 computed

以下面为例

new Vue({
  el: '#app',
  data: {
    selectedType: '',
    selectedCountry: '',
    selectedYear: '',
    items: [{
        name: 'Nolan',
        type: 'mercedes',
        year: '2020',
        country: 'england'
      },
      {
        name: 'Edgar',
        type: 'bmw',
        year: '2020',
        country: 'belgium'
      },
      {
        name: 'John',
        type: 'bmw',
        year: '2019',
        country: 'england'
      },
      {
        name: 'Axel',
        type: 'mercedes',
        year: '2020',
        country: 'england'
      }
    ],
    searchResult: [],
  },
  methods: {
    search: function() {
      let filterType = this.selectedType,
        filterCountry = this.selectedCountry,
        filterYear = this.selectedYear

      this.searchResult = this.items.filter(function(item) {
        let filtered = true
        if (filterType && filterType.length > 0) {
          filtered = item.type == filterType
        }
        if (filtered) {
          if (filterCountry && filterCountry.length > 0) {
            filtered = item.country == filterCountry
          }
        }
        if (filtered) {
          if (filterYear && filterYear.length > 0) {
            filtered = item.year == filterYear
          }
        }
        return filtered
      })
    }
  },
  mounted() {
    this.search()
  }
})
.list-item {
  margin-top: 50px;
}

.card {
  box-shadow: 0px 10px 16px rgba(0, 0, 0, 0.16);
  width: 400px;
  padding: 20px 30px;
  margin-bottom: 30px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.1/vue.js"></script>

<div id="app">
  <select v-model="selectedType">
    <option value="" disabled selected hidden>Type</option>
    <option value="mercedes">Mercedes</option>
    <option value="bmw">BMW</option>
  </select>

  <select v-model="selectedCountry">
    <option value="" disabled selected hidden>Country</option>
    <option value="belgium">Belgium</option>
    <option value="england">England</option>
  </select>

  <select v-model="selectedYear">
    <option value="" disabled selected hidden>Year</option>
    <option value="2019">2019</option>
    <option value="2020">2020</option>
  </select>

  <button @click="search">Search</button>

  <div class="list-item" v-for="item in searchResult">
    <div class="card">
      <p>Name: {{ item.name }}</p>
      <p>Car: {{ item.type }}</p>
      <p>Year: {{ item.year }}</p>
      <p>Country: {{ item.country }}</p>
    </div>
  </div>
</div>