Bootstrap is the internet’s most popular web page framework. I’m unaware of a quicker way to build a responsive web project than with Bootstrap.

But since my tool of choice for adding dynamic functionality to a page is Vue.js now, it’s becoming harder to justify Bootstrap because it brings with it some baggage…I’m talking about jQuery.

This is not jQuery bashing, it’s just recognising that there are some significant downsides in having to add jQuery to a project when you’re already using a framework like Vue:

Overhead. jQuery will add 30KB to your page size.

jQuery can be tricky to configure with bundlers like Webpack.

When you put Vue in charge of the DOM you don’t want to have jQuery in there messing up the place.

If you’re using Vue but you really want to build upon Bootstrap’s CSS framework, then you have a tough choice: is the compromise of adding jQuery worth it?

Before you decide, there is another option…

Note: this article was originally posted here on the Vue.js Developers blog on 2016/11/07

Drop jQuery and Bootstrap’s Javascript plugins entirely

There’s a great project called vue-strap which replaces the jQuery plugins in Bootstrap with Vue.js-built plugins. So you’ll have all your Bootstrap plugins like modals, carousel, tabs etc powered by Vue.

However, at the time of writing, vue-strap is still only supporting Vue 1.x and Bootstrap 3.x.

But if you only need to use a few of Bootstrap’s widgets, I think it’s so easy just to roll your own bespoke plugins with Vue.js, that you might not need vue-strap either.

Let me show you how to set up a few common Bootstrap plugins from scratch using Vue.js.

DIY Bootstrap widgets powered by Vue.js

Tabs

We’ll start simple with tabs. For every tab, there must be an accompanying tab pane. The showing/hiding is achieved by adding/removing a class “active” to both the tab and the tab pane, so that’s what Vue will need to handle.

<div id="tabs">

<ul class="nav nav-tabs">

<li><a>Tab 1</a></li>

<li><a>Tab 2</a></li>

</ul>

<div class="tab-content">

<div class="tab-pane">Pane 1</div>

<div class="tab-pane">Pane 2</div>

</div>

</div>

We’ll track which tab is currently selected with a variable tab, and use this to add/remove the “active” class on each tab and tab pane:

<div id="tabs">

<ul class="nav nav-tabs">

<li v-bind:class="{ active: tab === 1}"><a>Tab 1</a></li>

<li v-bind:class="{ active: tab === 2}"><a>Tab 2</a></li>

</ul>

<div class="tab-content">

<div class="tab-pane" v-bind:class="{ active: tab === 1}">

Pane 1</div>

<div class="tab-pane" v-bind:class="{ active: tab === 2}">

Pane 2</div>

</div>

</div>

We also need to listen for a click event on each tab which updates our tab variable:

<div id="tabs">

<ul class="nav nav-tabs">

<li v-bind:class="{ active: tab === 1}" v-on:click="tab = 1">

<a>Tab 1</a>

</li>

<li v-bind:class="{ active: tab === 2}" v-on:click="tab = 2">

<a>Tab 2</a>

</li>

</ul>

<div class="tab-content">

<div class="tab-pane" v-bind:class="{ active: tab === 1}">

Pane 1</div>

<div class="tab-pane" v-bind:class="{ active: tab === 2}">

Pane 2</div>

</div>

</div>

Finally the Javascript:

new Vue({

el: '#tabs',

data: {

// Tab 1 is selected by default

tab: 1

}

});

There are a few more improvements we could make which I won’t show for the sake of brevity of this article:

Wrap up the Javascript into a Vue Components so we can reuse the tabs code across the site.

For a really compact template and super fast rendering, put the tab and tab pane content into an array data property and use v-for to print out a list of tabs/tab panes.

Modal

The modal dialog is one of my favourite Bootstrap plugins. Similar to tabs we show/hide a modal by adding/removing a class “in” which is triggered by open and close buttons:

<div id="app" v-bind:class=" { 'modal-open': show }">

<button class="btn btn-primary" v-on:click="toggle">

Open

</button>

<div class="modal" tabindex="-1" v-bind:class="{ in: show }"

v-bind:style="modalStyle">

<div class="modal-dialog">

<div class="modal-content">

<div class="modal-body">

<p>Vue-powered modal!</p>

</div>

<div class="modal-footer">

<button class="btn" v-on:click="toggle">Close</button>

</div>

</div>

</div>

</div>

</div>

With a Bootstrap modal we need dynamic inline style on the dialog. We achieve this with the v-bind:style directive which receives a “style object” from a computed property. The computed property will re-calculate every time the dependent variable show changes:

new Vue({

el: '#app',

data: {

show: false

},

methods: {

toggle() { this.show = !this.show; }

},

computed: {

modalStyle() {

return this.show ?

{ 'padding-left': '0px;', display: 'block' } : {};

}

}

});

You might also enhance your modal by using a Vue Transition to animate a fade on the modal as it enters and leaves the DOM.

Consider using Vue.js on your next Bootstrap project and retiring jQuery

Not only can you replace jQuery with Vue.js in Bootstrap, but maybe you should. Whether you use vue-strap or roll your own plugins, here are some enticing advantages of Vue:

Vue’s DOM update system allows superior UI performance and responsiveness when compared to jQuery.

Vue is designed for building small, isolated chunks of UI and is great at that task, so Vue-built widgets will be more extendable and maintainable than jQuery ones.

Bootstrap widgets have notoriously messy templates, so Vue can help alleviate that with its flexible template options like JSX, single page components, render functions, class and style binding etc.

Keep in mind that Vue doesn’t support IE8, but you might otherwise consider it for your next Bootstrap project.