如何在 Vue 中使用 "v-for" 过滤结果.JS



我正在使用使用Bootstrap-Vue构建的选项卡式界面。单击其中一个选项卡时,我使用v-for在折叠/下拉列表中呈现一些数据,该折叠/下拉列表显示为网格。

目前,我有一个选项卡显示所有结果,在使用以下方法时效果很好 (注意: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 个结果。每个对象中的每个值都会更改,但我想使用prizeType1Name 和 prizeType2Name来检查它们是否包含字符串 ">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"的对象。

我尝试过的:

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

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 个只需要显示过滤结果,具体取决于prizeType1Name 或 prizeType2Name中是否存在">CTW"、">IW">或">OG"。

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

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成为一个组合属性
  • 为您的条件创建一个对象数组(可能重构了这个想法以满足您的需求或更加动态(
// Inside data
filterCriteria: [
{ name: 'prizeType1Name', value: 'CTW' },
{ name: 'prizeType2Name', value: 'CTW' }
];
  • 创建一个函数以返回对象数组
    • 创建一个空数组以将我们的选择推入
    • 循环浏览奖品 按键对象
    • 在循环中,迭代标准
    • 将所选内容分配给数组,前提是它尚不存在
    • 返回数组
// 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答案

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

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

最新更新