简体   繁体   中英

Javascript - How to filter data with multiple arrays in Vue.js?

I'm using Vue.js 3 and I have a filter here for one array in this case genres, but how to connect with another array for example here for a category? I tried the same way but I got only duplicate

Can https://stackoverflow.com/users/3330981/tauzn you maybe check this if you have time?

Here is my code

<template>
<div>
   <form>
      <input type="checkbox" name="drama" v-model="filters.drama"/>
      <label for="drama">drama</label>
      <input type="checkbox" name="comedy" v-model="filters.comedy"/>
      <label for="comedy">comedy</label>
      <input type="checkbox" name="horror" v-model="filters.horror"/>
      <label for="horror">horror</label>
      <input type="checkbox" name="polovno" v-model="filters.new"/>
      <label for="new">new</label>
   </form>
   <div v-for="(movie) in filteredMovies" :key="movie.title">
      <div>
        {{ movie.title }}
      </div>
    </div>
</div>
</template>

<script>
  export default {
    data: ()=>({
      filters: {
        horror: true,
        comedy: true,
        drama: true,
        new:true,
        old:true,
      },
      movies: [
        { title: 'Movia A', genres: ['horror'], category:['new']},
        { title: 'Movia B', genres: ['comedy'], category:['old']},
        { title: 'Movia C', genres: ['drama'], category:['new']},
        { title: 'Movia D',genres: ['horror'], category:['new']},
      ]
    }),
    computed: {
      filteredMovies(){
        return this.movies.filter( movie => {
          let selectedGenres = Object.keys(this.filters).filter(item => this.filters[item] === true)
    
                    return movie.genres.some(item => selectedGenres.includes(item))
        })
      },
      filteredMoviesByCategory(){
        return this.movies.filter( movie => {

          let selectedCategory = Object.keys(this.filters).filter(item => this.filters[item] === true)
          
           return movie.category.some(item => selectedCategory.includes(item))
        })
      }
    },


  }
</script>

So I have checkboxes and this works very well for genres filtering but how to connect that to works with another array in this case category? I'm new at Vue.js and this will help me a lot

Here is Gif how everything works now在此处输入图像描述

I found a solution, with other dummy data but works.

Here is my code

<template>
  <h5>List of Products</h5>

        <h3>Filter</h3> 
        <button v-on:click="resetOptions">Reset</button>
        <button v-on:click="sorting">Sorting</button>
        <button v-on:click="sorting2">Sorting2</button>
        <select v-model="category">
            <option value="Accessories">Accessories</option>
            <option value="Laptop">Laptop</option>
            <option value="Stationary">Stationary</option>
        </select> 
         <select v-model="gradovi">
            <option value="Podgorica">Podgorica</option>
            <option value="Niksic">Niksic</option>
            <option value="Herceg Novi">Herceg Novi</option>
        </select> 

        <input type="text" v-model="name" placeholder="Filter By Name"/>

        <label for="vol">Price (between 0 and 1000):</label>

        <input type="range" v-model.trim="range" min="0" max="1000" step="10"/>  
        <ul>
            <li v-for="product in filterProducts" :key="product.name"> Product Name : {{product.name}} - Price : {{product.price}} ({{product.category}}) 
                {{product.gradovi}}
            </li>
        </ul>
</template>

<script>
export default {
 data: ()=> ( {
            gradovi:'',
            category: '',
            name: '',
            range: '0',
            products: [
                { name: "Keyboard", price: 44, category: 'Accessories', gradovi:'Podgorica'},
                { name: "Mouse", price: 20, category: 'Accessories', gradovi:'Niksic'},
                { name: "Monitor", price: 399, category: 'Accessories', gradovi:'Herceg Novi'},
                { name: "Dell XPS", price: 599, category: 'Laptop', gradovi:'Podgorica'},
                { name: "MacBook Pro", price: 899, category: 'Laptop', gradovi:'Podgorica'},
                { name: "Pencil Box", price: 6, category: 'Stationary', gradovi:'Niksic'},
                { name: "Pen", price: 2, category: 'Stationary', gradovi:'Niksic'},
                { name: "USB Cable", price: 7, category: 'Accessories', gradovi:'Herceg Novi'},
                { name: "Eraser", price: 2, category: 'Stationary', gradovi:'Podgorica'},
                { name: "Highlighter", price: 5, category: 'Stationary', gradovi:'Niksic'}
            ]
        }),

              computed: {
            filterProducts: function(){
                return this.filterProductsByName(this.filterProductsByRange(this.filterProductsByCity(this.filterProductsByCategory(this.products))))
            },
        },
        
        methods: {

            filterProductsByCategory: function(products){
                return products.filter(product => !product.category.indexOf(this.category))
            },

            filterProductsByName: function(products) {
                return products.filter(product => !product.name.toLowerCase().indexOf(this.name.toLowerCase()))
            },

            filterProductsByCity: function(products) {
                return products.filter(product => !product.gradovi.indexOf(this.gradovi))
            },

            filterProductsByRange: function(products){
                return products.filter(product => (product.price >= 0 && product.price <= this.range) ? product : '')
            },

            sorting:function(){
                this.products.sort((a,b)=>(a.price > b.price) ? 1 : -1)
            },
             sorting2:function(){
                this.products.sort((a,b)=>(a.price < b.price) ? 1 : -1)
            },

            resetOptions:function(){
                this.category='',
                this.gradovi='',
                this.name='',
                this.range='1000'
            },
        },

}
</script>

<style>

</style>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM