如何在 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 个结果。每个对象中的每个值都会更改,但我想使用 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].prizeType1
或 this.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=” ]" 存在于 prizeType1Name 或 prizeType2Name 中。
我不确定我是否理解正确,但你可以试试:
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 匹配查询的结果。
我正在使用 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 个结果。每个对象中的每个值都会更改,但我想使用 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].prizeType1
或 this.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=” ]" 存在于 prizeType1Name 或 prizeType2Name 中。
我不确定我是否理解正确,但你可以试试:
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 匹配查询的结果。