Методы Vue порядок выполнения

#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 решения :

  1. поместите ваши другие функции в «затем» «actGetTabFilter».
  2. используйте ожидание и сохраните возвращенное значение

в обоих случаях это приведет к ожиданию ответа перед выполнением остальных функций

Комментарии:

1. Спасибо. Первый из них сработал. Но не могли бы вы объяснить мне второй вариант?

Ответ №2:

вы можете использовать этот синтаксис

 async created() {
    let response = await(YourAsyncFunction())
    //you can save it in data here if necessary
    YourOtherAsyncFunction()
}
 

таким образом, он будет ждать возврата первой функции, прежде чем выполнять вторую.
(не забудьте добавить async перед созданным вами методом)

Комментарии:

1. если вам нужна дополнительная информация : Асинхронное ожидание