Skip to content

Using Bootstrap 5 with Vue 3

Bootstrap 5 brings significant improvements over previous versions, most notably the removal of jQuery dependency, making it more compatible with modern JavaScript frameworks like Vue 3. This guide covers the best practices for integrating Bootstrap 5 into your Vue 3 projects.

Installation and Setup

To get started, install Bootstrap 5 and its peer dependency Popper.js:

shell
npm install bootstrap @popperjs/core

In your Vue application's entry point (typically main.js or main.ts), import the Bootstrap CSS and JavaScript:

js
import "bootstrap/dist/css/bootstrap.min.css";
import "bootstrap";

This basic setup allows you to use Bootstrap's CSS classes throughout your Vue components.

Using Bootstrap Components

Direct Data Attribute Approach

The simplest way to use Bootstrap components is through data-bs-* attributes:

html
<template>
  <div class="container">
    <h1 class="text-center my-5">Hello, Bootstrap with Vue 3!</h1>
    
    <!-- Bootstrap dropdown example -->
    <div class="dropdown">
      <button
        class="btn btn-secondary dropdown-toggle"
        type="button"
        id="dropdownMenuButton1"
        data-bs-toggle="dropdown"
        aria-expanded="false"
      >
        Check Bootstrap
      </button>
      <ul class="dropdown-menu" aria-labelledby="dropdownMenuButton1">
        <li><a class="dropdown-item" href="#">Action</a></li>
        <li><a class="dropdown-item" href="#">Another action</a></li>
        <li><a class="dropdown-item" href="#">Something else here</a></li>
      </ul>
    </div>
    
    <!-- Bootstrap collapse component -->
    <button 
      class="btn btn-primary mt-3" 
      data-bs-target="#collapseTarget" 
      data-bs-toggle="collapse">
      Bootstrap collapse
    </button>
    <div class="collapse py-2" id="collapseTarget">
      This is the toggle-able content!
    </div>
  </div>
</template>

WARNING

Note the data-bs- prefix (not data-) for Bootstrap 5 attributes. This is a key changes from Bootstrap 4.

Programmatic Component Approach

For more control, you can wrap Bootstrap components in Vue components:

js
import { Popover } from 'bootstrap';

export default {
  mounted() {
    new Popover(this.$refs.popoverTrigger, {
      title: this.title,
      content: this.content,
      trigger: this.trigger
    });
  },
  props: {
    title: {
      type: String,
      default: 'Popover title'
    },
    content: {
      type: String,
      default: 'Popover content'
    },
    trigger: {
      type: String,
      default: 'click'
    }
  }
};
html
<template>
  <button ref="popoverTrigger" class="btn btn-danger">
    Hover for popover
  </button>
</template>

Important Considerations

JavaScript Compatibility

While Bootstrap CSS works with any framework, the Bootstrap JavaScript may conflict with Vue's DOM management. Both may attempt to manipulate the same DOM elements, potentially causing issues like dropdowns stuck in "open" state.

For complex applications, consider using framework-specific alternatives like BootstrapVue (when Vue 3 support is available) or creating your own Vue wrapper components.

Custom Modal Implementation Example

Here's how to implement a Bootstrap modal with Vue-controlled state:

html
<template>
  <div>
    <button type="button" class="btn btn-primary" @click="modalToggle">
      Open Modal
    </button>
    
    <div
      ref="modal"
      class="modal fade"
      :class="{ show: active, 'd-block': active }"
      tabindex="-1"
    >
      <div class="modal-dialog">
        <div class="modal-content">
          <div class="modal-header">
            <h5 class="modal-title">Modal title</h5>
            <button
              type="button"
              class="btn-close"
              @click="modalToggle"
              aria-label="Close"
            ></button>
          </div>
          <div class="modal-body">
            <p>Modal body text goes here.</p>
          </div>
        </div>
      </div>
    </div>
    
    <div v-if="active" class="modal-backdrop fade show"></div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      active: false,
    };
  },
  methods: {
    modalToggle() {
      const body = document.querySelector("body");
      this.active = !this.active;
      this.active ? 
        body.classList.add("modal-open") : 
        body.classList.remove("modal-open");
    },
  },
};
</script>

Best Practices

  1. Use framework-specific packages when available for production applications
  2. Test interactive components thoroughly to ensure no conflicts between Bootstrap and Vue
  3. Consider creating wrapper components for complex Bootstrap components
  4. Stay updated on BootstrapVue's Vue 3 compatibility progress

INFO

BootstrapVue, the official Vue integration for Bootstrap, currently only supports Vue 2. Monitor their GitHub repository for Vue 3 support updates.

By following these guidelines, you can successfully integrate Bootstrap 5 with Vue 3 while minimizing potential conflicts and maintaining a clean codebase.