admin管理员组

文章数量:1321241

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);     
        });
    }
}

本文标签: javascriptFiltering list by two or more selects in Vuejs 20Stack Overflow