如何在 Vue.JS 中使用 "v-for" 筛选结果

How to filter results using "v-for" in Vue.JS

我正在使用 Bootstrap-Vue 构建的选项卡式界面。单击这些选项卡之一时,我正在使用 v-for 在显示为网格的 accordion/dropdown 中呈现一些数据。

目前,我有一个显示所有结果的选项卡,使用以下方法时效果很好 (注意:prizesData 就是我用 axios 调用后存储 response.data 的地方):

<div class="col-sm-12 col-md-6 col-lg-3 w-100 prize-dropdown-wrapper pb-5"
 v-for="(prize, name, index) in prizesData"
 :key="index"
>
<!--REMAINDER OF MARKUP GOES HERE-->
</div>

我的 JSON 结构看起来像这样,除了我总共有 43 个结果。每个对象中的每个值都会更改,但我想使用 prizeType1NameprizeType2Name 来检查它们是否包含字符串“CTW ", "IW" 或 "OG":

{
  "1": [
      {
         "prizeTitle": "",
         "prizeImage": "",
         "prizeFirstLineText": "",
         "prizeType1": {
            "Image": "",
            "Line1": "",
            "Line2": ""
         },
         "prizeType2": {
            "Image": "",
            "Line1": "",
            "Line2": ""
         },
         "prizeTermsText": "",
         "prizeType1Name": "CTW",
         "prizeType2Name": ""
      }
   ],
  "2": [
      {
         "prizeTitle": "",
         "prizeImage": "",
         "prizeFirstLineText": "",
         "prizeType1": {
            "Image": "",
            "Line1": "",
            "Line2": ""
         },
         "prizeType2": {
            "Image": "",
            "Line1": "",
            "Line2": ""
         },
         "prizeTermsText": "",
         "prizeType1Name": "IW",
         "prizeType2Name": ""
      }
   ]
}

要访问我正在使用的这些值之一:

this.prizesData[name][0].prizeType1this.prizesData[name][0].prizeType2

我很难理解如何过滤我的结果。例如,如果我单击名为 (CTW) 的选项卡,我只想显示 JSON 文件中包含 "CTW" 的结果。或者,如果单击名为 "IW" 的选项卡,则结果应该针对包含 "IW".

的对象

我试过的:

添加了 filteredPrizes 以将过滤后的奖品存储为对象以供以后访问

data() {
    return {
      prizesData: {},
      filteredPrizes: {},
    };
  }

我尝试对从 JSON 文件收到的现有 prizesData 对象使用 filter(),我添加了这与我获取 JSON 文件的方法相同。

getPrizesInfo() {
      const self = this;
      //Get Error Validation JSON
      axios
        .get("/data/prizes.json")
        .then(response => (this.prizesData = response.data));

      this.filteredPrizes = this.prizesData.filter(prize =>
        this.prizesData[name][0].prizeType1.includes("CTW")
      );
    }

我期待的是: 我有 4 个选项卡,第一个工作正常(显示全部)。其他 3 个只需要显示过滤结果,具体取决于“CTW”“IW”或“OG[=57=” ]" 存在于 prizeType1NameprizeType2Name 中。

我不确定我是否理解正确,但你可以试试:

new Vue({
  el: '#app',

  data() {
    return {
      myData: {
        prizeTitle: '',
        prizeImage: '',
        prizeFirstLineText: '',
        prizeType1: {
          Image: 'CTW',
          Line1: 'CTW',
          Line2: 'CTW'
        },
        prizeType2: {
          Image: 'IW',
          Line1: 'IW',
          Line2: 'IW'
        },
        prizeTermsText: '',
        prizeType1Name: 'CTW',
        prizeType2Name: 'IW'
      },
      prizesData: {}
    }
  },

  methods: {
    filter (criteria) {
      // getting keyName with value equals to criteria
      const key = 
          Object.keys(this.myData)
            .filter(key => this.myData[key] === criteria)
              .pop().replace('Name', '')

      this.prizesData = this.myData[key]
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.min.js"></script>
<div id="app">
  <button @click="filter('CTW')">CTW</button>
  <button @click="filter('IW')">IW</button>
  <pre>{{ prizesData }}</pre>
</div>

  • 让你的 filteredPrizes 成为一个 comupted 属性
  • 根据您的标准创建一个对象数组(可能重构该想法以满足您的需要或更加动态)
// Inside data
filterCriteria: [
  { name: 'prizeType1Name', value: 'CTW' },
  { name: 'prizeType2Name', value: 'CTW' }
];
  • 为return对象数组创建一个函数
    • 创建一个空数组以将我们的选择推入
    • 按键循环遍历奖品对象
    • 在循环内,迭代条件
    • 将选择分配给数组,前提是它尚不存在
    • return数组
// Inside methods
getFilteredPrizes(prizes, criteria) {
  selected = [];

  Object.keys(prizes).forEach(a => {
    criteria.forEach(b => {
      if (prizes[a][0][b.name] === b.value && !selected.contains(prizes[a][0])) {
        selected.push(prizes[a][0]);
      }
    });
   });

   return selected;
}

new Vue({
  el: '#app',
  data() {
    return {
      prizesData: {
        "1": [
            {
               "prizeTitle": "",
               "prizeImage": "",
               "prizeFirstLineText": "",
               "prizeType1": {
                  "Image": "",
                  "Line1": "",
                  "Line2": ""
               },
               "prizeType2": {
                  "Image": "",
                  "Line1": "",
                  "Line2": ""
               },
               "prizeTermsText": "",
               "prizeType1Name": "CTW",
               "prizeType2Name": ""
            }
         ],
        "2": [
          {
             "prizeTitle": "",
             "prizeImage": "",
             "prizeFirstLineText": "",
             "prizeType1": {
                "Image": "",
                "Line1": "",
                "Line2": ""
             },
             "prizeType2": {
                "Image": "",
                "Line1": "",
                "Line2": ""
             },
             "prizeTermsText": "",
             "prizeType1Name": "IW",
             "prizeType2Name": ""
          }
       ]
      },
      filterCriteria: [
        { name: 'prizeType1Name', value: 'CTW' },
        { name: 'prizeType2Name', value: 'CTW' }
      ]
    }
  },
  computed: {
    filteredPrizes() {
      return this.getFilteredPrizes(this.prizesData, this.filterCriteria);
    }
  },
  methods: {
    getFilteredPrizes(prizes, criteria) {
      selected = [];

      Object.keys(prizes).forEach(a => {
        criteria.forEach(b => {
          if (prizes[a][0][b.name] === b.value && !selected.includes(prizes[a][0])) {
            selected.push(prizes[a][0]);
          }
        });
      });

      return selected;
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.min.js"></script>
<div id="app">
  <h3>Filtered Prizes</h3>
  <pre>{{ filteredPrizes }}</pre>
</div>

正如@seantunwin 所建议的,我将我的 JSON 从一个对象更改为一个数组 - 需要一些整理和格式化,但在较长的 运行.

中让生活变得更轻松

所以我的新结构现在看起来像这样:

[

{

"id": 1,

"prizeTitle": "",

"prizeImage": "",

"prizeFirstLineText": "",

"prizeType1": {

"Image": "",

"Line1": "",

"Line2": ""

},

"prizeType2": {

"Image": "",

"Line1": "",

"Line2": ""

},

"prizeTermsText": "",

"prizeType1Name": "CTW",

"prizeType2Name": ""

}

]

然后我使用了@Our_Benefactors 建议的计算 属性,如下所示:

computed: {

filteredPrizesByQuery: function() {

*return* this.prizes.filter(prize => {

*return* (

prize.prizeType1Name.match(this.query) ||

prize.prizeType2Name.match(this.query)

);

});

}

}

我使用 v-for 包装了我想要循环的代码并引用了计算的 属性:

<div

class="col-sm-12 col-md-6 col-lg-3 w-100 prize-dropdown-wrapper pb-5"

v-for="(prize, index) in filteredPrizesByQuery"

:key="index"

>

I set query as an empty string as default in data

data() {

*return* {

query: "",

prizes: [],

}

};

我在选项卡上添加了一个点击事件来更改查询值,类似于@christiancarrillo answer

<b-tab title="IW" @click="query='IW'">

现在,当我单击选项卡时,值会更改为 CTW、IW 或 OG,并且计算的 属性 会检查这些值并 returns 匹配查询的结果。