How to Create a Spinner With Bootstrap Vue
A spinner is used to indicate an ongoing process to the user. They are suitable for operations that don’t take very long to complete, and they help to enhance the responsiveness of an application. Read on to learn more about the Vue Bootstrap spinner component and the various customization options it provides.
The Boostrap Vue Spinner Component (b-spinner)
Boostrap Vue provides the b-spinner component for creating spinners. It starts spinning as soon as it has been rendered on the page.
<template>
<div
id="app"
class="text-center"
>
<b-spinner></b-spinner>
</div>
</template>

Border spinner
We can use the type prop to display a particular type of spinner. By default the type is set to border, which makes the spinner transparent and gives it a thick circle border.
<template>
<div
id="app"
class="text-center"
>
<b-spinner type="border"></b-spinner>
</div>
</template>

Grow spinner
Alternatively, we can set type to grow to make the spinner repeatedly grow into view and fade out.
<template>
<div
id="app"
class="text-center"
>
<b-spinner type="grow"></b-spinner>
</div>
</template>

Spinner colors
b-spinner comes with a variant prop that lets us customize the color of the spinner. There are a bunch of values it can take, including primary, secondary, danger, warning, success, and info.
Here we create multiple border spinners with many different colors:
<template>
<div
id="app"
class="text-center d-flex justify-content-between"
>
<b-spinner
v-for="variant in variants"
:key="variant"
:variant="variant"
></b-spinner>
</div>
</template>
<script>
export default {
data() {
return {
variants: [
'primary',
'secondary',
'danger',
'warning',
'success',
'info',
],
};
},
};
</script>

We can also customize the color of grow spinners with the variant prop:
<template>
<div
id="app"
class="text-center d-flex justify-content-between"
>
<b-spinner
v-for="variant in variants"
:key="variant"
:variant="variant"
type="grow"
></b-spinner>
</div>
</template>
<script>
export default {
data() {
return {
variants: [
'primary',
'secondary',
'danger',
'warning',
'success',
'info',
],
};
},
};
</script>

For more color customization options we can set the color CSS property using inline styles.
<template>
<div
id="app"
class="text-center m-3 d-flex justify-content-between"
>
<b-spinner style="color: orange"></b-spinner>
<b-spinner style="color: blue"></b-spinner>
<b-spinner style="color: #800080"></b-spinner>
<b-spinner style="color: green"></b-spinner>
<b-spinner style="color: red"></b-spinner>
<b-spinner style="color: #424242"></b-spinner>
</div>
</template>

Spinner size
Setting the small prop to true on the b-spinner creates a spinner of a smaller size.
<template>
<div
id="app"
class="text-center"
>
<b-spinner small></b-spinner>
<b-spinner
type="grow"
small
></b-spinner>
</div>
</template>

For more size customization options, we can add some inline styles to customize the width and height CSS properties.
<template>
<div
id="app"
class="text-center"
>
<b-spinner
style="width: 50px; height: 50px"
></b-spinner>
<b-spinner
type="grow"
style="width: 50px; height: 50px"
></b-spinner>
</div>
</template>

Spinner margin
We can add any of the Bootstrap Vue margin utility classes to a b-spinner to adjust its spacing. Here we use the ms-4 class from Bootstrap to add a left margin to the second spinner:
<template>
<div
id="app"
class="text-center"
>
<b-spinner></b-spinner>
<b-spinner
type="grow"
class="ms-4"
></b-spinner>
</div>
</template>

Spinner in button
One good use for a spinner is within a button, to indicate that an action is currently taking place.
<template>
<div
id="app"
class="text-center"
>
<b-button variant="primary">
<b-spinner small></b-spinner>
Loading...
</b-button>
</div>
</template>

Here’s a more practical example of using spinners within buttons. When the button is clicked to save, it changes its text and shows the spinner to indicate the ongoing save operation (simulated with a timeout). Then it hides the spinner and changes the text again after the save.
<template>
<div
id="app"
class="text-center m-3"
>
<b-button
variant="primary"
@click="save"
>
<b-spinner
small
v-if="status === 'saving'"
></b-spinner>
{{ buttonText }}
</b-button>
</div>
</template>
<script>
export default {
data() {
return {
status: 'unsaved',
};
},
computed: {
buttonText() {
if (this.status === 'unsaved') return 'Save';
else if (this.status === 'saving') return 'Saving';
else return 'Saved';
},
},
methods: {
save() {
this.status = 'saving';
setTimeout(() => {
this.status = 'saved';
}, 2000);
},
},
};
</script>
We use the status data property to track the current save state, and we create a buttonText computed property to determine what the button label should be from status.

Conclusion
A spinner is useful for indicating app operations in the process of being completed. In this article, we learned how to use the spinner component from Bootstrap Vue (b-spinner) to easily create and customize spinners.
