无法过滤Vue js中的对象数组

时间:2018-05-15 05:51:41

标签: javascript vue.js

我想按流派过滤游戏。 pdList是对象(游戏)的数组。为此,我使用的是Array.filter()。 但它不起作用。下面是代码。如果我的方法错了,请纠正我。它也没有在控制台中给出任何错误。

Vuejs代码:

new Vue({
el: "#app",
data: {
    currentFilter:"all",
    pdList:[,
            {
            "title": "Double Dragon: Neon",
            "url": "/games/double-dragon-neon/xbox-360-131320",
            "platform": "Xbox 360",
            "score": 3,
            "genre": "Fighting",
            "editors_choice": "N",
            "release_year": 2012
            },
            {
            "title": "Guild Wars 2",
            "url": "/games/guild-wars-2/pc-896298",
            "platform": "PC",
            "score": 9,
            "genre": "RPG",
            "editors_choice": "Y",
            "release_year": 2012
            }]
},
methods: {
    filterByGenre:function(filterby){
    this.currentFilter = filterby;
    },
    filteredGames:function(pdList){
    console.log("inside filtergames");
    if(this.currentFilter == "all"){

        return pdList;
    }else{
        return  pdList.filter(function(game){
        console.log(this.currentFilter);
        return game.genre == this.currentFilter;
        });
    }
    }
}
})

HTML

<div id="app">
  <h2>Game Lister:</h2>
  <ol>
    <li v-for="game in filteredGames(pdList)">

      {{game.genre}}

    </li>
  </ol>
</div>

 <select v-model="currentFilter">
  <option value="all">all</option>
  <option value="Platformer">Platformer</option>
  <option value="Platformer">Puzzle</option>
  <option value="Platformer">Sports</option>
  <option value="Platformer">Strategy</option>

  </select>

4 个答案:

答案 0 :(得分:3)

这个想法不正确。代码中的一些缺陷:

在模板中:

  1. 选择选项超出div#app - 将导致选择未显示
  2. 所有选项,但“全部”在选择
  3. 中具有相同的值

    在ViewModel中:

      pdList中的
    1. data()[,开头 - 这将打破代码
    2. 一个简单的计算函数将完成所有操作 - 并且您没有使用模板中使用的任何方法
    3. 解决方案是:

      <强>模板

      <div id="app">
        <h2>Game Lister:</h2>
        <ol>
          <li v-for="game in filteredGames">{{game.title}}</li>
        </ol>
      
        <select v-model="currentFilter">
          <option value="all">all</option>
          <option value="Fighting">Fighting</option>
          <option value="RPG">RPG</option>
        </select>
      </div>
      

      <强>视图模型

      data: {
          currentFilter: "all",
          pdList: [{
            "title": "Double Dragon: Neon",
            "url": "/games/double-dragon-neon/xbox-360-131320",
            "platform": "Xbox 360",
            "score": 3,
            "genre": "Fighting",
            "editors_choice": "N",
            "release_year": 2012
          }, {
            "title": "Guild Wars 2",
            "url": "/games/guild-wars-2/pc-896298",
            "platform": "PC",
            "score": 9,
            "genre": "RPG",
            "editors_choice": "Y",
            "release_year": 2012
          }]
      },
      computed: {
          filteredGames () {
              const self = this;
            if (self.currentFilter === 'all') {
              return self.pdList;
            } else {
              return self.pdList.filter(function(game) {
                return self.currentFilter === game.genre;
              });
            }
          }
      }
      

答案 1 :(得分:0)

每当重新渲染发生时,方法调用将始终运行该函数。要知道它取决于this.pdList,您不需要解析它。

HTML

<li v-for="game in filteredGames()">

  {{game.genre}}

</li>

Vuejs

filteredGames:function(){
    console.log("inside filtergames");
    if(this.currentFilter == "all"){

        return this.pdList;
    } else {
        return  this.pdList.filter(function(game){
          console.log(this.currentFilter);
          return game.genre == this.currentFilter;
        });
    }
}

答案 2 :(得分:0)

在纠正@Naiful提到的语法问题后,您也可以尝试这种方法。

模板:

<div id="app">
 <h2>Game Lister:</h2>
 <ol>
   <li v-for="game in filteredGames">
    {{game.genre}}
   </li>
 </ol>
 <select v-model="currentFilter">
  <option value="all">all</option>
  <option value="Platformer">Platformer</option>
  <option value="Platformer">Puzzle</option>
  <option value="Platformer">Sports</option>
  <option value="Platformer">Strategy</option>
 </select>
</div>

然后,您可以在currentFilter模型上加注并调用filterByGenre函数来更新filteredGames

VueJs代码:

new Vue({
 el: "#app",
 data (){
  return {
   currentFilter:"all",
   filteredGames : [],
   pdList:[{
        "title": "Double Dragon: Neon",
        "url": "/games/double-dragon-neon/xbox-360-131320",
        "platform": "Xbox 360",
        "score": 3,
        "genre": "Fighting",
        "editors_choice": "N",
        "release_year": 2012
        },
        {
        "title": "Guild Wars 2",
        "url": "/games/guild-wars-2/pc-896298",
        "platform": "PC",
        "score": 9,
        "genre": "RPG",
        "editors_choice": "Y",
        "release_year": 2012
        }]
  }
 },
 created (){
   this.filterByGenre();
 },
 watch : {
  'currentFilter' (){
   this.filterByGenre();
  }
 },
 methods: {
  filterByGenre (){
    this.filteredGames = [];
    if(this.currentFilter == "all"){
     this.filteredGames = this.filteredGames.concat(this.pdList);
    }else{
     this.filteredGames = this.pdList.filter(game => game.genre == this.currentFilter);
    }
  }
 }
});

P.S。 - 在您的vue代码中,数据应该是VueJS官方文档中推荐的function which returns an object

答案 3 :(得分:0)

还添加了搜索功能。

filteredGames () {
            const self = this;
        //for searching
        if(this.search.length > 0){
            return self.pdList.filter(function(game) {
                console.log(game.title)
               return game.title.toLowerCase().indexOf(self.search.toLowerCase()) >= 0;
            });
        }else{
            if (self.currentFilter === 'all') {
            return self.pdList;
        } else {
            return self.pdList.filter(function(game) {
               return self.currentFilter === game.genre;
            });
        }
        }


        }