Skip to main content

Vue.js Bootstrap Vue

Introduction

Bootstrap Vue is a powerful UI component library that combines the functionality of Vue.js with the design system of Bootstrap. It allows Vue.js developers to implement Bootstrap 4 components and grid system in their applications without having to use jQuery or Bootstrap's JavaScript. BootstrapVue provides one of the most comprehensive implementations of Bootstrap v4 components and grid system for Vue.js, making it an excellent choice for building responsive, mobile-first sites.

In this tutorial, we'll explore how to integrate BootstrapVue into your Vue.js applications, understand its core features, and build practical UI interfaces using its components.

Getting Started with Bootstrap Vue

Installation

To get started with BootstrapVue, you need to add it to your Vue.js project:

bash
# With npm
npm install bootstrap bootstrap-vue

# With yarn
yarn add bootstrap bootstrap-vue

Setting up BootstrapVue

After installation, you need to import BootstrapVue in your main entry file (usually main.js):

javascript
import Vue from 'vue'
import { BootstrapVue, IconsPlugin } from 'bootstrap-vue'

// Import Bootstrap and BootstrapVue CSS files
import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap-vue/dist/bootstrap-vue.css'

// Make BootstrapVue available throughout your project
Vue.use(BootstrapVue)

// Optionally install the BootstrapVue icon components plugin
Vue.use(IconsPlugin)

Core Components and Features

BootstrapVue comes with a wide range of components that cover most of the UI needs in modern web applications. Let's explore some of the key components:

1. Layout and Grid System

BootstrapVue provides a powerful grid system based on flexbox, allowing you to create responsive layouts easily:

html
<template>
<div>
<b-container>
<b-row>
<b-col cols="12" md="6">
<div class="bg-light p-3 border">Column 1</div>
</b-col>
<b-col cols="12" md="6">
<div class="bg-light p-3 border">Column 2</div>
</b-col>
</b-row>
</b-container>
</div>
</template>

This code creates a two-column layout that stacks vertically on mobile devices (screen width < 768px) and displays horizontally on medium-sized screens and larger.

2. Form Components

BootstrapVue simplifies form creation with pre-styled components:

html
<template>
<div>
<b-form @submit="onSubmit">
<b-form-group
id="input-group-1"
label="Email address:"
label-for="input-1"
description="We'll never share your email with anyone else."
>
<b-form-input
id="input-1"
v-model="form.email"
type="email"
placeholder="Enter email"
required
></b-form-input>
</b-form-group>

<b-form-group id="input-group-2" label="Your Name:" label-for="input-2">
<b-form-input
id="input-2"
v-model="form.name"
placeholder="Enter name"
required
></b-form-input>
</b-form-group>

<b-button type="submit" variant="primary">Submit</b-button>
</b-form>
</div>
</template>

<script>
export default {
data() {
return {
form: {
email: '',
name: ''
}
}
},
methods: {
onSubmit(event) {
event.preventDefault()
alert(JSON.stringify(this.form))
}
}
}
</script>

3. Alert Component

Alerts are useful for providing feedback to users:

html
<template>
<div>
<b-alert show variant="success">Success Alert</b-alert>
<b-alert show variant="danger">Danger Alert</b-alert>
<b-alert
dismissible
fade
:show="showDismissibleAlert"
@dismissed="showDismissibleAlert=false"
variant="warning"
>
Dismissible Warning Alert
</b-alert>
<b-button @click="showDismissibleAlert = true">
Show dismissible alert
</b-button>
</div>
</template>

<script>
export default {
data() {
return {
showDismissibleAlert: false
}
}
}
</script>

4. Card Component

Cards are flexible containers that can include headers, footers, and various content:

html
<template>
<div>
<b-card
title="Card Title"
img-src="https://picsum.photos/600/300/?image=25"
img-alt="Image"
img-top
tag="article"
style="max-width: 20rem;"
class="mb-2"
>
<b-card-text>
Some quick example text to build on the card title and make up the bulk of the card's content.
</b-card-text>
<b-button href="#" variant="primary">Go somewhere</b-button>
</b-card>
</div>
</template>

5. Modal Component

Modals are useful for creating dialogs, notifications, or custom content:

html
<template>
<div>
<b-button v-b-modal.modal-1>Launch Modal</b-button>

<b-modal id="modal-1" title="BootstrapVue Modal">
<p class="my-4">Hello from modal!</p>
<template #modal-footer>
<b-button variant="secondary" @click="$bvModal.hide('modal-1')">
Close
</b-button>
<b-button variant="primary" @click="handleOk">
OK
</b-button>
</template>
</b-modal>
</div>
</template>

<script>
export default {
methods: {
handleOk() {
// Handle the OK button click
this.$bvModal.hide('modal-1')
}
}
}
</script>

Practical Example: Building a Product Listing Page

Let's create a practical example of a product listing page using Bootstrap Vue components:

html
<template>
<div>
<b-container>
<b-row class="my-4">
<b-col>
<h2>Our Products</h2>
</b-col>
<b-col cols="auto">
<b-form-input
v-model="searchQuery"
placeholder="Search products..."
class="mr-2"
></b-form-input>
</b-col>
</b-row>

<b-row>
<b-col
v-for="product in filteredProducts"
:key="product.id"
cols="12" md="6" lg="4"
class="mb-4"
>
<b-card
:title="product.name"
:img-src="product.image"
:img-alt="product.name"
img-top
tag="article"
class="h-100"
>
<b-card-text>
{{ product.description }}
</b-card-text>
<div class="d-flex justify-content-between align-items-center">
<b-badge variant="info">{{ product.category }}</b-badge>
<h5>${{ product.price }}</h5>
</div>
<template #footer>
<b-button variant="primary" @click="addToCart(product)">
Add to Cart
</b-button>
</template>
</b-card>
</b-col>
</b-row>

<!-- Shopping Cart Modal -->
<b-modal id="cart-modal" title="Your Cart" hide-footer>
<div v-if="cart.length === 0" class="text-center py-3">
Your cart is empty
</div>
<b-list-group v-else>
<b-list-group-item
v-for="(item, index) in cart"
:key="index"
class="d-flex justify-content-between align-items-center"
>
<div>
<h6 class="mb-0">{{ item.name }}</h6>
<small>${{ item.price }} x {{ item.quantity }}</small>
</div>
<div>
<b-button size="sm" variant="success" @click="addToCart(item)">+</b-button>
<b-button size="sm" variant="danger" @click="removeFromCart(index)">-</b-button>
</div>
</b-list-group-item>
</b-list-group>
<div class="d-flex justify-content-between mt-3">
<h5>Total: ${{ calculateTotal }}</h5>
<b-button variant="primary">Checkout</b-button>
</div>
</b-modal>

<!-- Floating Cart Button -->
<div class="floating-cart">
<b-button
pill
variant="primary"
v-b-modal.cart-modal
class="d-flex align-items-center"
>
<b-icon icon="cart-fill" class="mr-2"></b-icon>
{{ cartItemCount }} items
</b-button>
</div>
</b-container>
</div>
</template>

<script>
export default {
data() {
return {
searchQuery: '',
cart: [],
products: [
{
id: 1,
name: 'Smartphone',
description: 'Latest model with high-resolution camera and fast processor.',
price: 699,
category: 'Electronics',
image: 'https://placehold.it/300x200?text=Smartphone'
},
{
id: 2,
name: 'Wireless Headphones',
description: 'Noise cancelling headphones with long battery life.',
price: 199,
category: 'Audio',
image: 'https://placehold.it/300x200?text=Headphones'
},
{
id: 3,
name: 'Fitness Tracker',
description: 'Track your steps, heart rate and sleep patterns.',
price: 89,
category: 'Fitness',
image: 'https://placehold.it/300x200?text=Fitness+Tracker'
},
{
id: 4,
name: 'Coffee Maker',
description: 'Programmable coffee maker with built-in grinder.',
price: 129,
category: 'Kitchen',
image: 'https://placehold.it/300x200?text=Coffee+Maker'
}
]
}
},
computed: {
filteredProducts() {
if (!this.searchQuery) return this.products

const query = this.searchQuery.toLowerCase()
return this.products.filter(product =>
product.name.toLowerCase().includes(query) ||
product.description.toLowerCase().includes(query) ||
product.category.toLowerCase().includes(query)
)
},
cartItemCount() {
return this.cart.reduce((total, item) => total + item.quantity, 0)
},
calculateTotal() {
return this.cart.reduce((total, item) => total + (item.price * item.quantity), 0).toFixed(2)
}
},
methods: {
addToCart(product) {
const existingItem = this.cart.find(item => item.id === product.id)

if (existingItem) {
existingItem.quantity++
} else {
this.cart.push({
...product,
quantity: 1
})
}
},
removeFromCart(index) {
if (this.cart[index].quantity > 1) {
this.cart[index].quantity--
} else {
this.cart.splice(index, 1)
}
}
}
}
</script>

<style scoped>
.floating-cart {
position: fixed;
bottom: 20px;
right: 20px;
z-index: 1000;
}
</style>

This example creates a product listing page with search functionality, shopping cart modal, and floating cart button. It demonstrates several BootstrapVue components working together to create a cohesive user interface.

Using BootstrapVue Directives

BootstrapVue also provides several directives to enhance functionality:

Tooltip Directive

html
<template>
<div class="text-center my-3">
<b-button v-b-tooltip.hover title="Tooltip content">Hover Me</b-button>
</div>
</template>

Popover Directive

html
<template>
<div class="text-center my-3">
<b-button v-b-popover.hover="'Popover content'" title="Popover Title">
Hover Me
</b-button>
</div>
</template>
html
<template>
<div>
<b-button v-b-modal.my-modal>Open Modal</b-button>

<b-modal id="my-modal" title="Using v-b-modal Directive">
<p>This modal was triggered using a directive!</p>
</b-modal>
</div>
</template>

Best Practices for Using BootstrapVue

  1. Import only what you need: Instead of registering all components, you can import only the components you need to reduce bundle size:
javascript
import Vue from 'vue'
import { BButton, BModal } from 'bootstrap-vue'

Vue.component('b-button', BButton)
Vue.component('b-modal', BModal)

// Import the required CSS files
import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap-vue/dist/bootstrap-vue.css'
  1. Use slots for custom content: BootstrapVue components support slots for customizing content:
html
<b-card>
<template #header>
<h4 class="mb-0">Custom Header</h4>
</template>
<p>This is the main content.</p>
<template #footer>
<small class="text-muted">Last updated 3 mins ago</small>
</template>
</b-card>
  1. Leverage utility classes: BootstrapVue includes Bootstrap's utility classes for margin, padding, flexbox, etc.:
html
<div class="d-flex justify-content-between align-items-center mb-3 p-2 bg-light">
<h5 class="mb-0">Product Title</h5>
<b-badge variant="success">New</b-badge>
</div>

Responsive Design with BootstrapVue

BootstrapVue makes it easy to create responsive designs using breakpoints:

html
<template>
<b-container>
<b-row>
<!-- Stack on mobile, 2 columns on sm and above -->
<b-col cols="12" sm="6">Column 1</b-col>
<b-col cols="12" sm="6">Column 2</b-col>
</b-row>

<b-row>
<!-- 1 column on mobile, 2 columns on md, 3 columns on lg -->
<b-col cols="12" md="6" lg="4">Column 1</b-col>
<b-col cols="12" md="6" lg="4">Column 2</b-col>
<b-col cols="12" md="6" lg="4">Column 3</b-col>
</b-row>
</b-container>
</template>

Customizing BootstrapVue Themes

You can customize the look and feel of BootstrapVue components by overriding Bootstrap variables. Create a custom SCSS file:

scss
// custom.scss

// Override Bootstrap variables
$primary: #6a1b9a;
$secondary: #26a69a;
$success: #2e7d32;
$info: #0277bd;
$warning: #f57f17;
$danger: #d50000;

// Import Bootstrap and BootstrapVue source SCSS files
@import 'node_modules/bootstrap/scss/bootstrap';
@import 'node_modules/bootstrap-vue/src/index.scss';

Then in your main.js:

javascript
import Vue from 'vue'
import { BootstrapVue } from 'bootstrap-vue'

// Import custom SCSS
import './custom.scss'

Vue.use(BootstrapVue)

Summary

BootstrapVue offers Vue.js developers a robust library of components and utilities that accelerate UI development. By combining the flexibility of Vue.js with the proven design system of Bootstrap, developers can quickly build responsive, accessible, and visually appealing applications.

In this tutorial, we've covered:

  1. How to install and set up BootstrapVue
  2. Core components and their usage
  3. Building a practical product listing application
  4. Working with BootstrapVue directives
  5. Best practices and responsive design techniques
  6. Theme customization

BootstrapVue is particularly valuable for developers who need to create professional-looking interfaces quickly, or for projects where consistency and responsiveness are priorities.

Additional Resources

Practice Exercises

  1. Simple Form: Create a sign-up form with validation using BootstrapVue form components.
  2. Dashboard Layout: Build a responsive admin dashboard layout with sidebar, navbar, and content area.
  3. Data Table: Create a data table with sorting, filtering, and pagination using BootstrapVue's table component.
  4. Carousel: Implement a product carousel/slideshow with captioned images.
  5. Theme Customizer: Create a simple theme customizer that allows users to switch between different color schemes for your BootstrapVue application.

By completing these exercises, you'll gain practical experience with BootstrapVue's components and develop a strong foundation for building Vue.js applications with professional UI components.



If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)