Vue JS多个过滤器,一个数组

时间:2019-11-22 07:43:11

标签: javascript arrays vue.js

我目前正在努力使代码正确运行。我正在尝试基于数组创建一些动态生成的对象(已完成)。我已经实现了搜索功能,并且在一点上有一个工作过滤器(仅一个)。我尝试将过滤器链接起来,但是失败了:')我需要能够搜索并根据用户从3个类别(主题,价格,评论值)中选择的内容过滤数组,可能只是一两个或全部。

在过去12个小时的大部分时间里,我一直在为此苦苦挣扎D:只是字面上不知道如何用我实现所有方法的方式来解决这个问题:/ 主要代码如下:

let classes = {
  menu: [
    { topic: 'math', location: 'adadadas', price: 80, length: "120", time: "9:00", reviewStars: "3" },
    { topic: 'math', location: 'dsadassa', price: 90, length: "70", time: "11:00", reviewStars: "4" },
    { topic: 'math', location: 'dadass', price: 120, length: "30", time: "14:00", reviewStars: "1" },
    { topic: 'english', location: 'dasdsadas', price: 110, length: "45", time: "13:00", reviewStars: "2" },
    { topic: 'english', location: 'fsafasf', price: 90, length: "75", time: "11:00", reviewStars: "4" },
    { topic: 'english', location: 'fafasa', price: 90, length: "100", time: "17:00", reviewStars: "2" },
    { topic: 'english', location: 'fsasada', price: 130, length: "90", time: "15:00", reviewStars: "3" },
    { topic: 'piano', location: 'dsadsadsads', price: 120, length: "", time: "50", time: "13:00", reviewStars: "4" },
    { topic: 'piano', location: 'dsadasddsadsadas', price: 140, length: "40", time: "12:00", reviewStars: "1" }
  ],
  input: {
    topic: '',
    location: 'All',
    topics: 'All',
    price: 'All',
    review: 'All'
  },
  newAry: [],
  otherAry: [],
  filterText: null
};


var searchBar = new Vue({
  el: '#searchBar',
  data: classes,
  computed: {
    menuArray() {
      let vm = this
      let array = new Set()
      vm.menu.forEach(function (item) {
        array.add(item.location)
      })
      console.log(array)
      return vm.newAry = Array.from(array)

    },

    menuArrayReview() {
      let vm = this
      let array = new Set()
      vm.menu.forEach(function (item) {
        array.add(item.reviewStars)
      })
      console.log(array)
      return vm.newAry = Array.from(array)

    },
    menuArrayTopic() {
      let vm = this
      let array = new Set()
      vm.menu.forEach(function (item) {
        array.add(item.topic)
      })
      console.log(array)
      return vm.newAry = Array.from(array)

    },
    menuArrayPrice() {
      let vm = this
      let array = new Set()
      vm.menu.forEach(function (item) {
        array.add(item.price)
      })
      console.log(array)
      return vm.newAry = Array.from(array)

    },

    filterTypeTopic() {
      let vm = this
      if (vm.input.topic !== 'All') {
        return vm.otherAry.filter(function (item) {
          return item.topic === vm.input.topic
        })
      } else {
        return vm.otherAry
      }
    },

    filterTypePrice() {
      let vm = this
      if (vm.input.price !== 'All') {
        return vm.otherAry.filter(function (item) {
          return item.price === vm.input.price
        })
      } else {
        return vm.otherAry
      }
    },

    filterTypeReviews() {
      let vm = this
      if (vm.input.review !== 'All') {
        return vm.otherAry.filter(function (item) {
          return item.reviewStars === vm.input.review
        })
      } else {
        return vm.otherAry
      }
    },

    filterAryTopic() {
      let vm = this
      if (vm.input.topic) {
        return vm.filterTypeTopic().filter(function (item) {
          let content = item.topic.toLowerCase()
          let keyword = vm.input.topic.toLowerCase()
          return content.indexOf(keyword) !== -1
        })
      } else {
        return vm.filterTypeTopic
      }

    },

    filterAryPrice() {
      let vm = this
      if (vm.input.price) {
        return vm.filterTypePrice.filter(function (item) {
          let content = item.price.toLowerCase()
          let keyword = vm.input.price.toLowerCase()
          return content.indexOf(keyword) !== -1
        })
      } else {
        return vm.filterTypePrice
      }

    },

    filterAryReviews() {
      let vm = this
      if (vm.input.review) {
        return vm.filterTypeReviews().filter(function (item) {
          let content = item.reviewStars.toLowerCase()
          let keyword = vm.input.review.toLowerCase()
          return content.indexOf(keyword) !== -1
        })
      } else {
        vm.menu = vm.filterTypeReviews()
      }
    },

    filterType() {
      let vm = this
      if (vm.input.location !== 'All') {
        return vm.otherAry.filter(function (item) {
          return item.location === vm.input.location
        })
      } else {
        return vm.menu
      }
    },

    filterAry() {
      let vm = this
      if (vm.input.topic) {
        return vm.filterType.filter(function (item) {
            let content = item.topic.toLowerCase()
          let keyword = vm.input.topic.toLowerCase()
          return content.indexOf(keyword) !== -1
        })
      } else {
        return vm.filterType
      }
    },


    getAry() {
      let vm = this
      return vm.otherAry
    }
  },
  mounted: function () {
    newAry = classes;
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="searchBar">
    <div class="display-3 text-center my-5 text-secondary">Activities!  </div>
    <div class="container w-75">
      <div class="row mb-3">
        <div class="col-md-4">
          <div>
            <select name=""  class="form-control" v-model.trim="input.price">
              <option value="All" selected>All</option>
              <option :value="item" v-for="item in menuArrayPrice">{{item}}</option>
            </select>
            <select name=""  class="form-control" v-model.trim="input.topics">
              <option value="All" selected>All</option>
              <option :value="item" v-for="item in menuArrayTopic">{{item}}</option>
            </select>
            <select name=""  class="form-control" v-model.trim="input.reviews">
              <option value="All" selected>All</option>
              <option :value="item" v-for="item in menuArrayReview">{{item}}</option>
            </select>
          </div>
        </div>
        <div class="col-md-8">
          <input type="text" name=""  class="form-control" v-model.trim="input.topic" placeholder="search topics">
        </div>
      </div>
    </div>

    <div class="container w-75 mb-5">
      <div class="row">
        <div class="col-md-4" v-for="item in filterAry" >
          <ul class="course list-group mb-3">
            <li class="list-group-item text-accent h4 font-weight-bold">{{item.location}}</li>
            <li class="list-group-item text-secondary song-item d-flex flex-column ">
              {{item.topic}}{{item.price}}
          </ul>
        </div>
      </div>
    </div>
  </div>

2 个答案:

答案 0 :(得分:0)

您可以修改filterAry函数,如下所述逐个检查每个过滤条件

let classes = {
  menu: [
    { topic: 'math', location: 'adadadas', price: 80, length: "120", time: "9:00", reviewStars: "3" },
    { topic: 'math', location: 'dsadassa', price: 90, length: "70", time: "11:00", reviewStars: "4" },
    { topic: 'math', location: 'dadass', price: 120, length: "30", time: "14:00", reviewStars: "1" },
    { topic: 'english', location: 'dasdsadas', price: 110, length: "45", time: "13:00", reviewStars: "2" },
    { topic: 'english', location: 'fsafasf', price: 90, length: "75", time: "11:00", reviewStars: "4" },
    { topic: 'english', location: 'fafasa', price: 90, length: "100", time: "17:00", reviewStars: "2" },
    { topic: 'english', location: 'fsasada', price: 130, length: "90", time: "15:00", reviewStars: "3" },
    { topic: 'piano', location: 'dsadsadsads', price: 120, length: "", time: "50", time: "13:00", reviewStars: "4" },
    { topic: 'piano', location: 'dsadasddsadsadas', price: 140, length: "40", time: "12:00", reviewStars: "1" }
  ],
  input: {
    topic: '',
    location: 'All',
    topics: 'All',
    price: 'All',
    reviews: 'All'
  },
  newAry: [],
  otherAry: [],
  filterText: null
};


var searchBar = new Vue({
  el: '#searchBar',
  data: classes,
  computed: {
    menuArray() {
      let vm = this
      let array = new Set()
      vm.menu.forEach(function (item) {
        array.add(item.location)
      })
      console.log(array)
      return vm.newAry = Array.from(array)

    },

    menuArrayReview() {
      let vm = this
      let array = new Set()
      vm.menu.forEach(function (item) {
        array.add(item.reviewStars)
      })
      console.log(array)
      return vm.newAry = Array.from(array)

    },
    menuArrayTopic() {
      let vm = this
      let array = new Set()
      vm.menu.forEach(function (item) {
        array.add(item.topic)
      })
      console.log(array)
      return vm.newAry = Array.from(array)

    },
    menuArrayPrice() {
      let vm = this
      let array = new Set()
      vm.menu.forEach(function (item) {
        array.add(item.price)
      })
      console.log(array)
      return vm.newAry = Array.from(array)

    },

    filterTypeTopic() {
      let vm = this
      if (vm.input.topic !== 'All') {
        return vm.otherAry.filter(function (item) {
          return item.topic === vm.input.topic
        })
      } else {
        return vm.otherAry
      }
    },

    filterTypePrice() {
      let vm = this
      if (vm.input.price !== 'All') {
        return vm.otherAry.filter(function (item) {
          return item.price === vm.input.price
        })
      } else {
        return vm.otherAry
      }
    },

    filterTypeReviews() {
      let vm = this
      if (vm.input.review !== 'All') {
        return vm.otherAry.filter(function (item) {
          return item.reviewStars === vm.input.review
        })
      } else {
        return vm.otherAry
      }
    },

    filterAryTopic() {
      let vm = this
      if (vm.input.topic) {
        return vm.filterTypeTopic().filter(function (item) {
          let content = item.topic.toLowerCase()
          let keyword = vm.input.topic.toLowerCase()
          return content.indexOf(keyword) !== -1
        })
      } else {
        return vm.filterTypeTopic
      }

    },

    filterAryPrice() {
      let vm = this
      if (vm.input.price) {
        return vm.filterTypePrice.filter(function (item) {
          let content = item.price.toLowerCase()
          let keyword = vm.input.price.toLowerCase()
          return content.indexOf(keyword) !== -1
        })
      } else {
        return vm.filterTypePrice
      }

    },

    filterAryReviews() {
      let vm = this
      if (vm.input.review) {
        return vm.filterTypeReviews().filter(function (item) {
          let content = item.reviewStars.toLowerCase()
          let keyword = vm.input.review.toLowerCase()
          return content.indexOf(keyword) !== -1
        })
      } else {
        vm.menu = vm.filterTypeReviews()
      }
    },

    filterType() {
      let vm = this
      if (vm.input.location !== 'All') {
        return vm.otherAry.filter(function (item) {
          return item.location === vm.input.location
        })
      } else {
        return vm.menu
      }
    },

    filterAry() {
      let vm = this
      return vm.menu.filter(function(value){
        if(vm.input.topics.length && vm.input.topics!="All" && value.topic!=vm.input.topics) return false  
        if(vm.input.reviews.length && vm.input.reviews!="All" && value.reviewStars!=vm.input.reviews) return false  
        if(vm.input.price && vm.input.price!="All" && value.price!=vm.input.price) return false 
        if(vm.input.topic.length){
          return value.topic.indexOf(vm.input.topic) > -1
        }
      return true
      })
      
    },


    getAry() {
      let vm = this
      return vm.otherAry
    }
  },
  mounted: function () {
    newAry = classes;
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="searchBar">
    <div class="display-3 text-center my-5 text-secondary">Activities!  </div>
    <div class="container w-75">
      <div class="row mb-3">
        <div class="col-md-4">
          <div>
            <select name=""  class="form-control" v-model.trim="input.price">
              <option value="All" selected>All</option>
              <option :value="item" v-for="item in menuArrayPrice">{{item}}</option>
            </select>
            <select name=""  class="form-control" v-model.trim="input.topics">
              <option value="All" selected>All</option>
              <option :value="item" v-for="item in menuArrayTopic">{{item}}</option>
            </select>
            <select name=""  class="form-control" v-model.trim="input.reviews">
              <option value="All" selected>All</option>
              <option :value="item" v-for="item in menuArrayReview">{{item}}</option>
            </select>
          </div>
        </div>
        <div class="col-md-8">
          <input type="text" name=""  class="form-control" v-model.trim="input.topic" placeholder="search topics">
        </div>
      </div>
    </div>

    <div class="container w-75 mb-5">
      <div class="row">
        <div class="col-md-4" v-for="item in filterAry" >
          <ul class="course list-group mb-3">
            <li class="list-group-item text-accent h4 font-weight-bold">{{item.location}}</li>
            <li class="list-group-item text-secondary song-item d-flex flex-column ">
              {{item.topic}}{{item.price}}
          </ul>
        </div>
      </div>
    </div>
  </div>

答案 1 :(得分:0)

我明白了您在这里尝试做的事情,但是我认为您需要重新审视它。链式过滤器在这里是正确的方法,只需要使其与数据集一起正确使用即可。

这种类型的架构可能会起作用

data() {
  return {
    topic: 'All',
    location: 'All',
    // and rest of filterable parameters
  }
},

computed: {
    filteredAry () {
      const { topic, location } = this
      const filteredMenu = Array.from(menu);
      if (topic !== 'All') {
        filteredMenu.filter(item => item.topic === topic)
      }
      // ... and so on for all possible filter values
      return filteredMenu
    },
  },

然后在filteredAry循环中使用v-for来显示数据