Скелет-загрузчик Vuetify 2 с манипуляцией "загрузкой" в магазине Vuex - PullRequest
0 голосов
/ 29 мая 2020

Я использую компонент Vuetify v-skeleton-loader, обертывающий компонент v-data-table.

Компонент data-table использует разбиение на страницы и сортировку на стороне сервера.

Для выполнения sh при разбивке на страницы на стороне сервера документация предлагает просмотреть объект options из data-table и сделать новый вызов API с измененными параметрами.
В моем модуле магазина я установил state.loading = true до начала запроса API и state.loading = false сразу после того, как ответ зафиксирован в состоянии.
На компоненте data-table я прочитал это состояние для :loading prop.

Само по себе это работает нормально.

Когда я теперь оборачиваю data-table с v-skeleton-loader и помещаю опору :loading="loading", я получаю бесконечное l oop запросов API и рендеринга skeleton-loader.

Я догадываюсь, что после того, как запрос был разрешен и state.loading = false установлен, skeleton-loader отключается и data-table монтирует, изменяя наблюдаемые параметры, и запускается новый запрос API, который устанавливает state.loading = true и skeleton-loader снова монтируется, а data-table размонтируется. Что продолжается бесконечно.

Если это верно, как мне решить эту проблему?

Минимальный пример:

<template>
  <div>
    <v-card>
      <v-skeleton-loader
        :loading="loading"
        transition="scale-transition"
        height="500"
        type="table"
      >
        <v-data-table
          :headers="headers"
          :items="orders"
          :fixed-header="true"
          :server-items-length="totalItems"
          :options.sync="options"
        >
        </v-data-table>
      </v-skeleton-loader>
    </v-card>
  </div>
</template>

<script>
...
export default {
data() {
  return {
    options: {},
    ...
  }
},
  watch: {
    options: {
      handler() {
        this.getDataFromApi();
      },
      deep: true,
    },
  },
  methods: {
    getDataFromApi() {
      // build query from options
      this.$store.dispatch("orders/getOrdersCustom", query);
    },
  computed: {
    ...mapGetters("orders", ["orders"]),
    ...mapGetters("orders", ["loading"]),
  },
  mounted() {
    this.$store.dispatch("orders/getOrders");
  }
}
</script>

И модуль магазина:

const namespaced = true;

const state = {
  orders: [],
  loading: false,
};

const getters = {
  loading: (state) => state.loading,
  orders: (state) => state.orders.items,
};
const actions = {
  getOrdersCustom({ commit }, query) {
    commit("GET_ORDERS_REQUEST");

    return orderService.getOrdersCustom(query).then(
      (data) => commit("GET_ORDERS_SUCCESS", data),
      (error) => commit("GET_ORDERS_FAILURE", error)
    );
  },
}
const mutations = {
  GET_ORDERS_REQUEST(state) {
    state.loading = true;
  },
  GET_ORDERS_SUCCESS(state, data) {
    Vue.set(state.orders, "items", data["hydra:member"]);
    state.data = data;
    state.loading = false;
  },
}

1 Ответ

1 голос
/ 30 мая 2020

Я думаю, что в этой ситуации я бы сделал отдельную переменную в локальном состоянии компонента, чтобы отслеживать начальное состояние загрузки и отображать скелетный загрузчик на основе этого.

Как только начальный набор данных загружен, я бы использовал встроенный индикатор загрузки компонента таблицы данных для разбивки на страницы / сортировки данных .. имеет меньше смысла возвращаться к просмотру скелета, поскольку у вас уже есть что-то визуализируется для просмотра пользователем.

...