title: Vuetify 2 skeleton-loader with manipulating "loading" in Vuex store
body: <p>I am using the Vuetify <code>v-skeleton-loader</code> component wrapping a <code>v-data-table</code> component.</p>
  
  <p>The <code>data-table</code> component is using server-side pagination and sorting.</p>
  
  <p>To accomplish the server-side pagination, documentation suggests to watch the <code>options</code> object of the <code>data-table</code> and make a new API call with the changed options.<br>
  In my store module I set <code>state.loading = true</code> before the API request starts and <code>state.loading = false</code> right after the response is committed to the state.<br>
  On the <code>data-table</code> component I read that state for the <code>:loading</code> prop.</p>
  
  <p>On its own this works fine. </p>
  
  <p>When I now wrap the <code>data-table</code> with <code>v-skeleton-loader</code> and put the prop <code>:loading="loading"</code> I get an infinite loop of API requests and rendering of the <code>skeleton-loader</code>.</p>
  
  <p>My hunch is that after the request got resolved and <code>state.loading = false</code> is set, the <code>skeleton-loader</code> unmounts and <code>data-table</code> mounts, changing the options which are being watched and a new API request is fired which sets <code>state.loading = true</code> and the <code>skeleton-loader</code> is being mounted again while <code>data-table</code> is unmounted. Which continues infinetely.</p>
  
  <p>If that is correct, how do I resolve that issue?</p>
  
  <p>Minimal example:</p>
  
  <pre class="lang-js prettyprint-override"><code>&lt;template&gt;
    &lt;div&gt;
      &lt;v-card&gt;
        &lt;v-skeleton-loader
          :loading="loading"
          transition="scale-transition"
          height="500"
          type="table"
        &gt;
          &lt;v-data-table
            :headers="headers"
            :items="orders"
            :fixed-header="true"
            :server-items-length="totalItems"
            :options.sync="options"
          &gt;
          &lt;/v-data-table&gt;
        &lt;/v-skeleton-loader&gt;
      &lt;/v-card&gt;
    &lt;/div&gt;
  &lt;/template&gt;
  
  &lt;script&gt;
  ...
  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");
    }
  }
  &lt;/script&gt;
  </code></pre>
  
  <p>And the store module:</p>
  
  <pre class="lang-js prettyprint-override"><code>const namespaced = true;
  
  const state = {
    orders: [],
    loading: false,
  };
  
  const getters = {
    loading: (state) =&gt; state.loading,
    orders: (state) =&gt; state.orders.items,
  };
  const actions = {
    getOrdersCustom({ commit }, query) {
      commit("GET_ORDERS_REQUEST");
  
      return orderService.getOrdersCustom(query).then(
        (data) =&gt; commit("GET_ORDERS_SUCCESS", data),
        (error) =&gt; 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;
    },
  }
  </code></pre>