基于几个Multiselect框过滤结果,vue

FIltering results based on several Multiselect boxes, vue

我有一个 vue 组件,目前我在其中成功地显示了数据对象的结果,而且我还成功地创建了几个 multiselect 框。我的问题是过滤。

我知道如何从 multiselect 中设置单个值并比较它(使用 v-if)以便在 HTML div 中显示某些结果,但我现在完全迷失了如何基于多个 Multiselects 进行适当的过滤(特别是因为其中几个允许将值存储在数组中的多个选项)

我将我的代码片段放在下面,但我怎样才能正确地制作它,以便我可以根据 multiselects 的相应 v 模型中的所有值过滤结果,同时确保如果“所有商店”或“所有区域”是 selected,它允许 selection?

的所有值

-- 换句话说,如果用户不输入 selection 并且 multiselect 留在占位符上,则 select 的所有值都将是允许在 DOM 中显示(首先基于其他过滤器)

new Vue({
  el: "#app",
  components: {Multiselect: window.VueMultiselect.default},
  data: {
    selectedOutput: '',
    selectedAreas:[],
    selectedStores: [],
    selectedCategories: [],
    selectedShifts: [],
    shifts: [
      {id: 1, name: "First"},
      {id: 2, name: "Second"}
    ],
    categories: [
      {id: 1, name: "electronics"},
      {id: 1, name: "home"},
      {id: 1, name: "auto"},
    ],
    outputOptions: [
      {id:1, name: "Sold"},
      {id:2, name: "Purchased"}
    ],
    areas: [
        {value: 1, name: "East"},
        {value: 1, name: "West"},
    ],
    stores: [
        {value: 1, name: "One"},
        {value: 2, name: "Two"}
    ],
    workNumbers: [
        {
          "Adam": {
            "name": "Adam",
            "title": "Manager",
            "shift": "First",
            "category": "electronics",
            "area" : "East",
            "store": "One",
            "sold": 140,
            "purchased": 15
          },
          "Ben": {
            "name": "Ben",
            "title": "Manager",
            "shift": "First",
            "category": "electronics",
            "area" : "East",
            "store": "One",
            "sold": 225,
            "purchased": 77
          },
          "Suzie": {
            "name": "Suzie",
            "title": "Manager",
            "shift": "Second",
            "category": "home",
            "area" : "West",
            "store": "Two",
            "sold": 124,
            "purchased": 55
          },
          "Reg": {
            "name": "Reg",
            "title": "Manager",
            "shift": "Second",
            "category": "home",
            "area" : "West",
            "store": "Two",
            "sold": 66,
            "purchased": 36
          },
          "Kelly": {
            "name": "Kelly",
            "title": "Manager",
            "shift": "Second",
            "category": "home",
            "area" : "West",
            "store": "Two",
            "sold": 55,
            "purchased": 2
          },
        }
    ]
  },
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue-multiselect/3.0.0-alpha.2/vue-multiselect.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/vue-multiselect/3.0.0-alpha.2/dist/vue-multiselect.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div class="uk-width-2-10" style="position: relative !important;">
    <multiselect
      v-model="selectedOutput"
      :options="outputOptions"
      :multiple="false"
      :close-on-select="true"
      label="name"
      track-by="name"
      @input="checkOutput"
    ></multiselect>
</div>
<div class="uk-width-2-10" style="position:relative;">
    <multiselect
      v-model="selectedShifts"
      :options="shifts"
      :multiple="true"
      :close-on-select="true"
      placeholder="All shifts"
      label="name"
      track-by="name"
    ></multiselect>
</div>
<div class="uk-width-2-10" style="position: relative !important;">
    <multiselect
      v-model="selectedCategories"
      :options="categories"
      :multiple="true"
      :close-on-select="true"
      placeholder="All categories"
      label="name"
      track-by="id"
    ></multiselect>
</div>
<div class="uk-width-2-10" style="position: relative !important;">
    <multiselect
      v-model="selectedAreas"
      :options="areas"
      :multiple="true"
      :close-on-select="true"
      placeholder="All areas"
      label="name"
      track-by="name"
    ></multiselect>
</div>
<div class="uk-width-2-10" style="position: relative !important;">
    <multiselect
      v-model="selectedstores"
      :options="stores"
      :multiple="true"
      :close-on-select="true"
      placeholder="All stores"
      label="name"
      track-by="value"
    ></multiselect>
</div>

    <table>
    <tbody v-if="selectedOutput.name === 'Sold'">
      <tr v-for="(value, employee) in workNumbers"  :key="employee">
        <!-- this is where I need a condition to show based on filters, I believe-->
        <td>{{name}} - {{sold}}</td>
      </tr>
    </tbody>
    <tbody v-else-if="selectedOutput.name === 'Purchased'">
      <tr v-for="(value, employee) in workNumbers"  :key="employee">
        <!-- this is where I need a condition to show based on filters, I believe-->
        <td>{{name}} - {{purchased}}</td>
      </tr>
    </tbody>
    </table>
</div>

更新:

现在我转到另一个 table,它很相似,但它围绕不同的对象循环,以创建一个不同的模型,该模型也通过模态函数传递。

<tbody v-if="selectedOutput.name === 'Cubes'">
  <tr v-for="(value, employee) in workNumbers"  :key="employee">
    <td v-for="date in dates" :key="date" >
      <div v-for="(dateSpecificData, dateValue) in value.dates" :key="dateValue" @click="showModal(dateSpecificData)"   :style="'background: ' + (dateSpecificData.unavailable > 0 ? '#f7a7a3' : '#a8f0c6')">
        <div v-if="dateValue == date ">
          @{{dateSpecificData.sold}}
        </div>
      </div>
    </td>
  </tr>
</tbody>

你可以根据参数定义一个computed-property,returns过滤列表:

new Vue({
  el: "#app",
  components: { Multiselect: window.VueMultiselect.default },
  data: () => ({
    selectedOutput: '',
    outputOptions: [ {id:1, name: "Sold"}, {id:2, name: "Purchased"} ],
    selectedShifts: [],
    shifts: [ {id: 1, name: "First"}, {id: 2, name: "Second"} ],
    selectedCategories: [],
    categories: [ {id: 1, name: "electronics"}, {id: 2, name: "home"}, {id: 3, name: "auto"} ],
    selectedAreas:[],
    areas: [ {value: 1, name: "East"}, {value: 1, name: "West"} ],
    selectedStores: [],
    stores: [ {value: 1, name: "One"}, {value: 2, name: "Two"} ],
    workNumbers: [
      {
        "Adam": { "name": "Adam", "title": "Manager", "shift": "First", "category": "electronics", "area" : "East", "store": "One", "sold": 140, "purchased": 15 },
        "Ben": { "name": "Ben", "title": "Manager", "shift": "First", "category": "home", "area" : "West", "store": "Two", "sold": 225, "purchased": 77 },
        "Suzie": { "name": "Suzie", "title": "Manager", "shift": "Second", "category": "electronics", "area" : "East", "store": "One", "sold": 124, "purchased": 55 },
        "Reg": { "name": "Reg", "title": "Manager", "shift": "Second", "category": "home", "area" : "West", "store": "Two", "sold": 66, "purchased": 36 },
        "Kelly": { "name": "Kelly", "title": "Manager", "shift": "Second", "category": "auto", "area" : "West", "store": "Two", "sold": 55, "purchased": 2 }
      }
    ]
  }),
  methods: {
    filtedSelectedHelper(arr = [], val) {
      return arr.length ? arr.some(({ name }) => name === val) : true;
    }
  },
  computed: {
    filteredWorkNumbers () {
      const ouput = this.selectedOutput;
      const filteredList = 
        this.workNumbers
          .flatMap(Object.values)
          .filter(({ shift, category, area, store }) => 
            this.filtedSelectedHelper(this.selectedShifts, shift) &&
            this.filtedSelectedHelper(this.selectedCategories, category) &&
            this.filtedSelectedHelper(this.selectedAreas, area) &&
            this.filtedSelectedHelper(this.selectedStores, store) 
          );
       return !this.selectedOutput 
         ? filteredList.map(({ name, sold, purchased }) => 
             `${name} - ${sold} - ${purchased}`
           )
         : this.selectedOutput.name === "Sold"
           ? filteredList.map(({ name, sold }) => 
               `${name} - ${sold}`
             )
           : filteredList.map(({ name, purchased }) => 
               `${name} - ${purchased}`
             )
    }
  }
});
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-multiselect@2.1.0"></script>
<link rel="stylesheet" href="https://unpkg.com/vue-multiselect@2.1.0/dist/vue-multiselect.min.css">

<div id="app">
  <div class="uk-width-2-10" style="position: relative !important;">
    <multiselect
      v-model="selectedOutput"
      :options="outputOptions"
      :multiple="false"
      :close-on-select="true"
      label="name"
      track-by="name"
    ></multiselect>
  </div>
  <div class="uk-width-2-10" style="position:relative;">
    <multiselect
      v-model="selectedShifts"
      :options="shifts"
      :multiple="true"
      :close-on-select="true"
      placeholder="All shifts"
      label="name"
      track-by="name"
    ></multiselect>
  </div>
  <div class="uk-width-2-10" style="position: relative !important;">
    <multiselect
      v-model="selectedCategories"
      :options="categories"
      :multiple="true"
      :close-on-select="true"
      placeholder="All categories"
      label="name"
      track-by="id"
    ></multiselect>
  </div>
  <div class="uk-width-2-10" style="position: relative !important;">
    <multiselect
      v-model="selectedAreas"
      :options="areas"
      :multiple="true"
      :close-on-select="true"
      placeholder="All areas"
      label="name"
      track-by="name"
    ></multiselect>
  </div>
  <div class="uk-width-2-10" style="position: relative !important;">
    <multiselect
      v-model="selectedStores"
      :options="stores"
      :multiple="true"
      :close-on-select="true"
      placeholder="All stores"
      label="name"
      track-by="value"
    ></multiselect>
  </div>
  <table>
    <tbody>
      <tr v-for="str in filteredWorkNumbers" :key="str"><td>{{str}}</td></tr>
    </tbody>
  </table>
</div>

资源:

https://vuejs.org/v2/guide/computed.html

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flatMap

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/values

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map