53

I just got started with Vue.js and here is what I'm doing: I am rendering a list of products, and each product has a name, a gender and a size. I'd like users to be able to filter products by gender, by using an input to type the gender.

var vm = new Vue({
      el: '#product_index',
      data: {
        gender: "",
        products: [{name: "jean1", gender: "women", size: "S"}, {name: "jean2", gender: "men", size: "S"}]
      },
      methods:{
        updateGender: function(event){
          this.gender = $(event.target).val()
        }
      }
    }
  )

  <div v-for="product in products" v-if="...">
    <p>{{product.name}}<p>
  </div>
  <input v-on:change="updateGender">

I managed to get the gender updated, but I have an issue with the filtering part. When the page loads, I don't want any filtering. In the documentation, they advise to use v-if but it doesn't seem compatible with this configuration.

If I use v-if, I could do:

v-if="product.gender == gender" 

But again, this doesn't work when the page load because gender is empty. I couldn't find a workaround for this.

How should I approach this issue ?

5 Answers 5

105

Use computed properties - something like this (Example bellow filter items by type)

const app = new Vue({

  el: '#app',

  data: {
     search: '',
     items: [
       {name: 'Stackoverflow', type: 'development'},
       {name: 'Game of Thrones', type: 'serie'},
       {name: 'Jon Snow', type: 'actor'}
     ]
  },

  computed: {
    filteredItems() {
      return this.items.filter(item => {
         return item.type.toLowerCase().indexOf(this.search.toLowerCase()) > -1
      })
    }
  }

})

Template:

  <div id="app">

    <div v-for="item in filteredItems" >
      <p>{{item.name}}</p>
    </div>

    <input type="text" v-model="search">

  </div>

Demo: http://jsbin.com/dezokiwowu/edit?html,js,console,output

Sign up to request clarification or add additional context in comments.

4 Comments

This is the right way to go. Also take a look at the official docs vuejs.org/v2/guide/migration.html#Replacing-the-filterBy-Filter
hello, could you please check this question: stackoverflow.com/questions/54415053/…
what if we want to search this on "type" as well as "name"?
@BakhtawarGIll in that case you will need to have list of the keys you wanna filter on, and do same for each key.
4

You can try v-if="!gender || product.gender == gender"

2 Comments

Works like a charm! I'm using a simple filter based on a <select> value. Your solution is the best in that case! Thank you.
Be aware that this is against the style guide. Eslint will show a warning if used (see here).
4

Just modified @Nora's answer.

You need to change in the template as:

 <div id="product_index">
    <div v-for="product in products" v-if="!gender || product.gender===gender">
      <p>{{product.name}}<p>
    </div>
    <input v-on:change="updateGender">
  </div>

and in JS file as:

var vm = new Vue({
      el: '#product_index',
      data: {
        gender: "",
        products: [{name: "jean1", gender: "women", size: "S"}, {name: "jean2", gender: "men", size: "S"}]
      },
      methods:{
        updateGender: function(event){
          this.gender = event.target.value
        }
      }
    }
  );

Working Demo: https://jsbin.com/qocuraquki/edit?html,js,console,output

Comments

3
computed: {
        filteredItems() {
          return this.allStartupData.filter(item => {
            let byName =
              item.name.toLowerCase().indexOf(this.search.toLowerCase()) > -1;
            let byDescription =
              item.description.toLowerCase().indexOf(this.search.toLowerCase()) >
              -1;
            if (byName === true) {
              return byName;
            } else if (byDescription === true) {
              return byDescription;
            }
          });
        }
      }

and then u can iterate through filteredItems like e.g

 <v-flex v-for="(obj,index) in filteredItems" :key="index" xs12 md4>

Comments

0
computed: {
 filteredItems() {
  return myObject.filter((val) => { 
   return val.some((val) => val.toString().toLowerCase().includes(this.searchString))
  })
}}

Iterate over the Object as already described above

1 Comment

Please add the iteration, as the order of answers will change over time.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.