DunDev
DunDev

Reputation: 210

Why the filtered list doesn't appear in Vue.js?

This is my code:

HTML

<div class="container">
  <ul>
    <li v-for="item in myList | myFilter">
      {{ item.name }}
    </li>
  </ul>
</div>

JS

Vue.filter('myFilter', function(value){
  return value.filter(function(item) {
    return item.value >= 2;
  });
});

new Vue({
  el: '.container',
  data: {
    message: 'Hello world',
    myList: [
      {
        name: 'item1',
        value: 1
      },
      {
        name: 'item2',
        value: 2
      },
      {
        name: 'item3',
        value: 3
      }
    ]
  }
});

I created a filter named myFilter to filter out those items whose value is equal or bigger than 2. What I expected is that a filtered list with item2 and item3 will appear on the page, but in fact no thing appeared. It only shows all of the 3 items when I use <li v-for="item in myList">.

Is there any wrong with my code? I've looked around for this problem but not found any threads related to it.

Upvotes: 0

Views: 360

Answers (2)

SciFiThief
SciFiThief

Reputation: 586

What version of vue.js are you using?

In docs it says that: "Filters are usable in two places: mustache interpolations and v-bind expressions (the latter supported in 2.1.0+)."

So you can't use them in v-for directive. You can use computed instead, like this:

<div class="container">
  <ul>
    <li v-for="item in myFilteredList">
      {{ item.name }}
    </li>
  </ul>
</div>

new Vue({
  el: '.container',

  computed: {
    myFilteredList: function() {
      return this.myList.filter(function(item) {
          return item.value >= 2;
       });
      }
  },

  data: {
    message: 'Hello world',
    myList: [
      {
        name: 'item1',
        value: 1
      },
      {
        name: 'item2',
        value: 2
      },
      {
        name: 'item3',
        value: 3
      }
    ]
  }
});

Link to jsfiddle: https://jsfiddle.net/nryzwamm/.

However, ideally component should accept already filtered data passed to it from the outside. This will make your components more reusable, because they will contain less specific logic, like filtration, which may not be required in some other case.

Upvotes: 1

Botje
Botje

Reputation: 30830

Vue filters are only supposed to be used for re-processing text in interpolations or v-bind attributes. I think you're best off creating a computed property and looping over that in your v-for.

Upvotes: 1

Related Questions