В компоненте приложения Vue.js я беру информацию из хранилища Vuex. Внутри этого компонента я хочу показать v-overlay (preloader), пока данные из хранилища не будут быть недоступным Как правильно это сделать?

<template>

  <v-navigation-drawer
    v-model="open"
    absolute
    right>

    <v-overlay
      :absolute="absolute"
      :opacity="opacity"
      :value="overlay">

      <v-progress-circular
        indeterminate
        size="64">
      </v-progress-circular>

    </v-overlay>

    <v-checkbox
      v-if="!overlay"
      hide-details
      v-model="selectedGenders"
      v-for="gender in genders"
      :label="gender"
      :value="gender"
      :key="gender">
    </v-checkbox>

    <v-checkbox
      v-if="!overlay"
      hide-details
      v-model="selectedIncomeRanges"
      v-for="incomeRange in incomeRanges"
      :label="incomeRange"
      :value="incomeRange"
      :key="incomeRange">
    </v-checkbox>

  </v-navigation-drawer>

</template>

<script>
import {
  mapGetters,
  mapActions
} from 'vuex'

export default {
  name: 'RightNavigationDrawer',
  props: {
    open: {
      type: Boolean,
      default: false
    }
  },
  data () {
    return {
      absolute: true,
      opacity: 0.8,
      overlay: true,
      selectedGenders: [],
      selectedIncomeRanges: []
    }
  },
  mounted () {
    this.getGenders()
    this.getIncomeRanges()
  },
  computed: mapGetters('customStore', [
    'genders',
    'incomeRanges'
  ]),
  methods: mapActions('customStore', [
    'getGenders',
    'getIncomeRanges'
  ])
}
</script>
1
Nurzhan Nogerbek 29 Ноя 2019 в 12:54

2 ответа

Лучший ответ

В идеале вы должны отслеживать статус loading в vuex, чтобы он был доступен во всех ваших компонентах, как и в другом состоянии vuex. В своем магазине создайте логическое состояние loading. Затем создайте действие загрузки, которое будет вызываться в компоненте, например:

loadData({ commit, dispatch }) {
  commit('SET_LOADING', true);
  const loader1 = dispatch('getGenders')
  const loader2 = dispatch('getIncomeRanges')
  Promise.all([loader1, loader2]).then(() => {
    commit('SET_LOADING', false);
  })
}

Promise.all получает массив обещаний из ваших действий по загрузке и не будет разрешен, пока все эти обещания не будут решены. Просто убедитесь, что ваши действия getGenders и getIncomeRanges также возвращают обещания. Теперь в вашем компоненте сопоставьте только loading и loadData:

...mapState('customStore', ['loading']),
...mapActions('customStore', ['loadData'])

Измените mounted, чтобы вызвать это действие:

mounted() {
  this.loadData()
}

Теперь вы можете проверить loading где угодно вместо overlay во всех ваших компонентах. Это превосходный шаблон, потому что теперь loading сохраняется только один раз в vuex с вашим другим состоянием и доступен во всех ваших компонентах, а не управляется и передается локально.

Вот демонстрационная версия, где я моделирую вызовы AJAX с тайм-аутом. (В примере используется один файл для управления vuex + vue, поэтому он будет выглядеть немного иначе, но не должен быть слишком сложным для отслеживания.)

2
Dan 29 Ноя 2019 в 13:36

Поместите часы в overlay (получатель из хранилища Vuex). Допустим, значение равно this.overlay = true

watch: {
    overlay (val) {
      val && setTimeout(() => {
        this.overlay = false
      }, 3000)
    },
  },

Следуйте пером кода

0
stchr 29 Ноя 2019 в 10:07