Thore
Thore

Reputation: 1838

Vue: Reuse loading spinner template and logic

I've multiple (20+) pages where I need the following code:

<template>
    <template v-if="isLoading">
        <Spinner full size="medium" />
    </template>

    <template v-else>
        <p>Page data</p>
    </template>
</template>

<script>
    export default {
        computed: {
            isLoading() {
                return this.$store.getters['loader/isLoading'];
            },
        },
    };
</script>

I don't want to rewrite this part everytime I need it so is there a way to create something like a higher order component with access to the computed method and a way to add the hoc to the script tag of the different vue files? Or another way to archive this?

Upvotes: 1

Views: 817

Answers (1)

Igor Moraru
Igor Moraru

Reputation: 7729

I could recommend extending the spinner component where you want to show the spinner. I've created a boilerplate setup that show a very simple implementation of this approach here.

The main idea is to expose a default slot for you spinner component, and wrap the page component in that slot.

<template>
    <div>
        <Spinner v-if="isLoading" full size="medium" />

        <!-- Slot for component data -->
        <slot v-else></slot>
    </div>
</template>
<script>
    export default {
        computed: {
            isLoading() {
                return this.$store.getters['loader/isLoading'];
            },
        },
    };
</script>

Then in any component that you want to show the spinner:

<template>
  <spinner>
    <!-- Pass here the component content to be shown after the spinner is hidden -->
  </spinner>
</template>
<script>
  import Spinner from "./spinner";
  export default {
    name: "Page1",
    extends: Spinner,
    components: { Spinner }
  };
</script>

Upvotes: 1

Related Questions