#vue.js #vuex
Вопрос:
У меня есть приложение Vue, и есть метод, который вызывает данные из API, и на основе этих данных должны быть заполнены данные фильтра, чтобы их можно было отобразить в некоторых раскрывающихся меню, и на основе этих данных должны выполняться другие вызовы API. Я использую Vuex.
И я не могу понять, как сделать так, чтобы этот метод вызывался раньше других на Созданном крючке.
Итак, метод, который мне нужно вызвать сначала, чтобы данные для вызова других методов были готовы, — это «actGetTabFilter».
Это код, в котором находится фильтр:
<div class="container">
<div class="row m-1 pt-2">
<div class="col-sm" v-if="show == 1">
<div class="container">
<div class="row">
<div class="col-sm-3 w-auto m-auto">
<span
class="
font-RobotoBold
fs-16
font-weight-light
pr-2
"
>Área</span
>
</div>
<div class="col-sm-9">
<select
v-if="show == 1"
v-model="area_filter"
class="
dropdown-2
bor-rounded-xs bor-none
shadow-box-9
font-Roboto
text-capitalize
fs-14
w-100
p-md-2 p-1
"
>
<option :value="null" disabled>
Seleccionar...
</option>
<option
v-for="site in this.tabFilter.sites"
v-bind:value="site.id"
v-bind:key="site.id"
:selected="site.id == area_filter"
>
{{ site.name.toLowerCase() }}
</option>
</select>
</div>
</div>
</div>
</div>
<div
v-if="show == 1 || show == 0"
:class="show == 0 ? 'col-sm-3' : 'col-sm'"
>
<div class="container">
<div class="row">
<div class="col-sm-3 w-auto m-auto">
<span
class="
font-RobotoBold
fs-16
font-weight-light
pr-2
"
>Año</span
>
</div>
<div class="col-sm-9">
<select
v-model="year"
class="
dropdown-2
bor-rounded-xs bor-none
shadow-box-9
font-Roboto
text-capitalize
fs-14
w-100
p-md-2 p-1
"
>
<option :value="null" disabled>
Seleccionar...
</option>
<option
v-for="year in this.tabFilter.years"
v-bind:value="year"
v-bind:key="'year' year"
:selected="year == year"
>
{{ year }}
</option>
</select>
</div>
</div>
</div>
</div>
<div
v-if="show == 1 || show == 0"
:class="show == 0 ? 'col-sm-3' : 'col-sm'"
>
<div class="container">
<div class="row">
<div class="col-sm-3 w-auto m-auto">
<span
class="
font-RobotoBold
fs-16
font-weight-light
pr-2
"
>Mes</span
>
</div>
<div class="col-sm-9">
<select
v-model="month"
class="
dropdown-2
bor-rounded-xs bor-none
shadow-box-9
font-Roboto
text-capitalize
fs-14
w-100
p-md-2 p-1
"
>
<option :value="null" disabled>
Seleccionar...
</option>
<option
v-for="month in this.tabFilter.months"
v-bind:value="month"
v-bind:key="'month' month"
:selected="month == month"
>
{{ months_name[month] }}
</option>
</select>
</div>
</div>
</div>
</div>
<div :class="show == 0 ? 'col-sm-6' : 'col-sm-2'">
<div class="container">
<div class="row">
<div
class="col ml-auto"
:class="show == 0 ? 'col-sm-3' : ''"
>
<button
type="button"
class="
btn-red
bor-rounded-xs
w-100
float-right
p-0
"
style="height: 40px"
@click="filterAgain()"
>
Filtrar
</button>
</div>
</div>
</div>
</div>
</div>
</div>
и это код скрипта:
export default {
name: "Engagement",
mixins: [cvMixin, psi],
components: {
SecondaryNavbar,
MenuNavigation,
BarChart,
ButtonsMenu,
IndicatorsButtons,
LeaderRanking,
DoughnutChart,
FilterSwitch,
},
data() {
return {
isLoading: false,
is_data_fetched: false,
area: null,
area_filter: 7,
area_personalities: 1,
year: 2021,
month: 3,
filter: 1,
classification: 1,
actualIndicator: "",
id: 1,
actualIndicatorDesc: "",
category: [1],
categoryInfo: [],
ranking: [],
barData: {
labels: [],
data: [],
},
donutData: {
name: null,
labels: [],
data: [],
colors: [],
},
brandData: [],
barThick: 15,
site: "",
show: 1,
brand: {
id: 0,
name: null,
description: null,
image: null,
},
};
},
created() {
this.isLoading = true;
this.area = this.user.core_vp_id;
this.actGetTabFilter()
.then(() => {
this.isLoading = true;
this.tabFilter;
})
.catch((err) => {
console.error("Error: ", err);
})
.finally(() => {
this.month = this.tabFilter.months.slice(-1)[0];
this.year = this.tabFilter.years[0];
this.isLoading = false;
});
this.actGetLeaders()
.then(() => {
this.isLoading = true;
this.leadersList;
})
.catch((err) => {
console.error("Error: ", err);
})
.finally(() => {
this.isLoading = false;
});
this.actGetPersonalitiesAreas()
.then(() => {
this.personalitiesAreaList;
})
.catch((err) => {
console.error("Error: ", err);
})
.finally(() => {
this.isLoading = false;
});
this.getCategoriesInfo();
//Get Ranking, Chart and Improve Ranking Data
this.getGeneralFilterData(
this.filter,
this.category,
this.year,
this.month
);
this.getPersonalitiesData(this.area_personalities);
this.actGetLeadersInfo({ leader: [[30000423, 25]], year: 2021, month: 3 })
.then(() => {
this.leadersInfo;
})
.catch((err) => {
console.error("Error: ", err);
})
.finally(() => {
this.isLoading = false;
});
},
computed: {
...mapState("modCore", ["user"]),
...mapState("modIndicators", [
"tabFilter",
"leadersList",
"personalitiesAreaList",
"categoriesListData",
"generalFilterData",
"personalitiesData",
"leadersInfo",
]),
title() {
if (this.show == 2) {
return "Personalidades de tu equipo";
}
return "Ranking Líderes - " this.actualIndicator.toLowerCase();
},
datacollection() {
return this.fillData();
},
},
methods: {
...mapActions("modIndicators", [
"actGetTabFilter",
"actGetLeaders",
"actGetPersonalitiesAreas",
"actGetCategoriesInfo",
"actGetGeneralFilterData",
"actGetPersonalitiesData",
"actGetLeadersInfo",
]),
fillData() {
return this.donutData;
},
changeClassification(classification, id, name, description, show) {
this.classification = classification;
this.category = [id];
this.id = id;
this.actualIndicator = name;
this.actualIndicatorDesc = description;
if (show !== 2) {
this.getGeneralFilterData(
this.filter,
this.category,
this.year,
this.month
);
}
// this.updateRanking(id);
this.updateImproveRanking(id);
},
changeShow(number) {
this.show = number;
},
changeFilter() {
if (this.filter === 1) {
this.filter = 2;
this.barThick = 20;
} else {
this.filter = 1;
this.barThick = 15;
}
this.filterAgain();
},
filterAgain() {
this.getCategoriesInfo();
this.getGeneralFilterData(
this.filter,
this.category,
this.year,
this.month
);
},
filterPersonalities() {
this.getPersonalitiesData(this.area_personalities);
},
updateRanking(category_id) {
this.ranking = Object.values(
this.generalFilterData.filter((category) => {
return category.id == category_id;
})[0].ranking
);
this.ranking.sort(
(a, b) => parseFloat(b.average) - parseFloat(a.average)
);
},
updateImproveRanking(category_id) {
this.categoryInfo = this.categoriesListData.filter((category) => {
return category.id == category_id;
});
},
getGeneralFilterData(filter, category, year, month) {
// This filter brings the information for the bar chart
this.actGetGeneralFilterData({
filter: filter,
category: category,
year: year,
month: month,
})
.then(() => {
this.is_data_fetched = false;
this.actualIndicator = this.generalFilterData[0].name;
this.actualIndicatorDesc = this.generalFilterData[0].description;
this.ranking = Object.values(
this.generalFilterData.filter((category) => {
return category.id == this.id;
})[0].ranking
).sort((a, b) => parseFloat(b.average) - parseFloat(a.average));
let fetchedData = Object.values(
this.generalFilterData.filter((category) => {
return category.id == this.id;
})[0].calculate
);
this.getChartData(fetchedData, this.filter);
})
.catch((err) => {
console.error("Error: ", err);
})
.finally(() => {
this.is_data_fetched = true;
this.isLoading = false;
});
},
getCategoriesInfo() {
this.actGetCategoriesInfo({
area: this.area_filter,
year: this.year,
month: this.month,
})
.then(() => {
this.isLoading = true;
this.categoryInfo = this.categoriesListData.filter((category) => {
return category.id == this.id;
});
})
.catch((err) => {
console.error("Error: ", err);
})
.finally(() => {
this.isLoading = false;
});
},
getChartData(data, filter) {
this.barData.labels.length = 0;
this.barData.data.length = 0;
if (filter == 2) {
for (let i = 0; i < data.length; i ) {
this.barData.labels.push(data[i].month);
this.barData.data.push(Math.round(parseFloat(data[i].average)));
}
} else {
data.sort((a, b) => parseFloat(b.average) - parseFloat(a.average));
for (let i = 0; i < data.length; i ) {
let siteName = data[i].name.split(" ");
for (let i = 0; i < siteName.length; i ) {
siteName[i] =
siteName[i].charAt(0) siteName[i].slice(1).toLowerCase();
}
this.barData.labels.push(siteName.join(" "));
this.barData.data.push(Math.round(parseFloat(data[i].average)));
}
}
},
getPersonalitiesData(id) {
this.actGetPersonalitiesData({
id: id,
})
.then(() => {
this.personalitiesData;
this.is_data_fetched = false;
this.isLoading = true;
this.getBrandData();
this.brand.id = this.personalitiesData.calculate[0].profile.id;
this.brand.name = this.personalitiesData.calculate[0].profile.name;
this.brand.description =
this.personalitiesData.calculate[0].profile.description;
this.brand.image = this.personalitiesData.calculate[0].profile.image;
})
.catch((err) => {
console.error("Error: ", err);
})
.finally(() => {
this.is_data_fetched = true;
this.isLoading = false;
});
},
getDonutData() {
this.donutData.name = null;
this.donutData.labels.length = 0;
this.donutData.data.length = 0;
this.donutData.colors.length = 0;
this.donutData.name = this.personalitiesData.vp.name;
this.brandData.sort(
(a, b) => parseFloat(b.average) - parseFloat(a.average)
);
for (let i = 0; i < this.brandData.length; i ) {
this.donutData.labels.push(this.brandData[i].profile.name);
this.donutData.data.push(
Math.round(parseFloat(this.brandData[i].average))
);
this.donutData.colors.push(this.brandData[i].color);
}
},
changeBrand(id) {
this.brand.id = id;
this.filterBrand();
},
filterBrand() {
let filteredBrand = this.personalitiesData.calculate.filter(
(e) => e.profile.id == this.brand.id
);
this.brand.name = filteredBrand[0].profile.name;
this.brand.description = filteredBrand[0].profile.description;
this.brand.image = filteredBrand[0].profile.image;
return filteredBrand;
},
getBrandData() {
this.brandData = [];
for (let i = 0; i < this.personalitiesData.calculate.length; i ) {
this.personalitiesData.calculate[i].color = this.brandColors[i];
this.brandData.push(this.personalitiesData.calculate[i]);
}
this.getDonutData();
},
},
};
Ответ №1:
2 решения :
- поместите ваши другие функции в «затем» «actGetTabFilter».
- используйте ожидание и сохраните возвращенное значение
в обоих случаях это приведет к ожиданию ответа перед выполнением остальных функций
Комментарии:
1. Спасибо. Первый из них сработал. Но не могли бы вы объяснить мне второй вариант?
Ответ №2:
вы можете использовать этот синтаксис
async created() {
let response = await(YourAsyncFunction())
//you can save it in data here if necessary
YourOtherAsyncFunction()
}
таким образом, он будет ждать возврата первой функции, прежде чем выполнять вторую.
(не забудьте добавить async
перед созданным вами методом)
Комментарии:
1. если вам нужна дополнительная информация : Асинхронное ожидание