最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Filtering list by two or more selects in Vue.js 2.0 - Stack Overflow

programmeradmin2浏览0评论

Since in Vue 2.0 you can no longer chain together multiple pipeline filters to a list (|filterBy etc), how are you supposed to do this in a puted property if you have two or more select dropdowns?

I want the ability to sort by album title (from select 1) and by year (select 2).

<select v-model="albumFilter">
    <option value="All">All</option>
    <option value="Album 1">Album 1</option>
    <option value="Album 2">Album 2</option>
    <option value="Album 3">Album 3</option>
</select>

<select v-model="yearFilter">
    <option value="Year">Year</option>
    <option value="2017">2017</option>
    <option value="2016">2016</option>
    <option value="2015">2015</option>
</select>

<ul>
    <li v-for="review in filterByAlbum" v-if="review.type === 'recordReview'">
        <a :href="review.jsonUrl">
            [[ review.title ]]
        </a>
    </li>
</ul>

Vue js code:

data() {
    return {
        pressEntries: [],
        albumFilter: 'All',
        yearFilter: 'Year'
    }
},

filterByAlbum: function() {

    // Select 1 (Album Filter)
    switch (this.albumFilter) {
        case 'All':
            return this.pressEntries;
            break;

        case 'Neither':
            return this.pressEntries.filter(entry => {
                return entry.relatedRecording === null
            });
            break;

        default:
            return this.pressEntries.filter(entry => {
                return entry.relatedRecording === this.albumFilter
            });     
    }

    // Select 2 (Year Filter)
    if (this.yearFilter === 'Year') {
        return this.pressEntries;
    }
    else {
        return this.pressEntries.filter(entry => {
            let postDate = new Date(entry.postDate.date);
            return JSON.stringify(postDate.getFullYear()) === this.yearFilter;
        });
    }
}

The pressEntries data model gets data from an API, which I didn't bother including the code for. Each block of code for each select filter works on their own, but not together.

If the filterByAlbum in the v-for loop refers to the puted property, which then refers back to pressEntries data model, would it be possible to have two puted properties that the v-for runs through (like "filterByAlbum" and "'filterByYear`" for example)? Or do I need to figure out how to filter all the results in one massive puted property?

Since in Vue 2.0 you can no longer chain together multiple pipeline filters to a list (|filterBy etc), how are you supposed to do this in a puted property if you have two or more select dropdowns?

I want the ability to sort by album title (from select 1) and by year (select 2).

<select v-model="albumFilter">
    <option value="All">All</option>
    <option value="Album 1">Album 1</option>
    <option value="Album 2">Album 2</option>
    <option value="Album 3">Album 3</option>
</select>

<select v-model="yearFilter">
    <option value="Year">Year</option>
    <option value="2017">2017</option>
    <option value="2016">2016</option>
    <option value="2015">2015</option>
</select>

<ul>
    <li v-for="review in filterByAlbum" v-if="review.type === 'recordReview'">
        <a :href="review.jsonUrl">
            [[ review.title ]]
        </a>
    </li>
</ul>

Vue js code:

data() {
    return {
        pressEntries: [],
        albumFilter: 'All',
        yearFilter: 'Year'
    }
},

filterByAlbum: function() {

    // Select 1 (Album Filter)
    switch (this.albumFilter) {
        case 'All':
            return this.pressEntries;
            break;

        case 'Neither':
            return this.pressEntries.filter(entry => {
                return entry.relatedRecording === null
            });
            break;

        default:
            return this.pressEntries.filter(entry => {
                return entry.relatedRecording === this.albumFilter
            });     
    }

    // Select 2 (Year Filter)
    if (this.yearFilter === 'Year') {
        return this.pressEntries;
    }
    else {
        return this.pressEntries.filter(entry => {
            let postDate = new Date(entry.postDate.date);
            return JSON.stringify(postDate.getFullYear()) === this.yearFilter;
        });
    }
}

The pressEntries data model gets data from an API, which I didn't bother including the code for. Each block of code for each select filter works on their own, but not together.

If the filterByAlbum in the v-for loop refers to the puted property, which then refers back to pressEntries data model, would it be possible to have two puted properties that the v-for runs through (like "filterByAlbum" and "'filterByYear`" for example)? Or do I need to figure out how to filter all the results in one massive puted property?

Share Improve this question asked Mar 8, 2017 at 23:31 ModelesqueModelesque 3143 silver badges12 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 3

Here is an example of a puted that would work. You could move albumFilter and yearFilter into their own methods as well. Essentially using this kind of technique, you could assemble as many filters together as you wanted.

function filterByAlbum(){

  const albumFilter = entry => 
           (this.albumFilter == 'All') || 
           (this.albumFilter == 'Neither' && !entry.relatedRecording) ||
           (entry.relatedRecording === this.albumFilter);

  const yearFilter = entry => 
         (this.yearFilter == 'Year') || 
         (new Date(entry.postDate.date).getFullYear() == this.yearFilter);

  const reducer = (accumulator, entry) => {
    if (albumFilter(entry) && yearFilter(entry))
      accumulator.push(entry);
    return accumulator;
  }

  return this.pressEntries.reduce(reducer, []);
}

new Vue({
  el: "#app",
  data() {
    return {
        pressEntries,
        albumFilter: 'All',
        yearFilter: 'Year'
    }
  },
  puted:{
    filterByAlbum
  }
})

I had to guess at your data structure, but here is a working example.

This is my solution: You can easily add a 3 Selectbox

https://codepen.io/anon/pen/PjOoEN

function() {
    var vm = this;
    var category = vm.selectedCategory;
    var gender = vm.selectedGender;

    if(category === "All" && gender === "All") {
        return vm.people;
    } else {
        return vm.people.filter(function(person) {
            return  (category === 'All' || person.category === category) && (gender === 'All'  || person.gender === gender);     
        });
    }
}
发布评论

评论列表(0)

  1. 暂无评论