BootstrapVue is the Vue version of Bootstrap. Like the plain JavaScript version of Bootstrap, it has many kinds of elements to let us style our page and make them look good.
BoostrapVue has the same elements, but they’re all available as Vue components. Therefore, we can add them straight into our Vue app without much hassle.
In this article, we’ll look at how use BootstrapVue in our Vue app to make it look good.
Getting Started
Getting started with BootstrapVue is easy. We need Vue 2.6 in our app but Vue 2.6.11 is recommended. At least Bootstrap 4.3.1 is required. Also, PortalVue 2.1 is required by Toasts.
To install it, we run:
npm install vue bootstrap-vue bootstrap
Then we register the BootstrapVue library in our app so we can use the components and directives in our app’s components.
Assuming that we used the Vue CLI to generate our Vue project, we add the following code register the BootstrapVue libraries in our app:
main.js
:
import Vue from "vue";
import App from "./App.vue";
import { BootstrapVue, IconsPlugin } from "bootstrap-vue";
import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap-vue/dist/bootstrap-vue.css'
Vue.use(BootstrapVue);
Vue.use(IconsPlugin);
Vue.config.productionTip = false;
new Vue({
render: h => h(App)
}).$mount("#app");
In the code above, we imported the CSS and the called Vue.use
to register BootstrapVue
for the core library and IconsPlugin
for the icons.
To register individual components and directives manually, we can write the following in the entry point file of our Vue app:
Vue.component('b-modal', BModal)
Vue.directive('b-modal', VBModal)
The individual components of the BootstrapVue library can also be imported individually into our app. For instance, if we only want to include the Bootstrap modal in our app, we write:
import { ModalPlugin } from 'bootstrap-vue'
Vue.use(ModalPlugin)
in the same file.
We can also import the component straight into our component if we want to use them in our component. For instance, we can write:
import { BModal, VBModal } from 'bootstrap-vue'
Vue.component('modal-component', {
components: {
'b-modal': BModal
},
directives: {
'b-modal': VBModal
}
})
to import the modal from BootstrapVue and then register them in our component so that we can use them.
Basic Form Controls
One of the common components in a web app are probably forms and the corresponding inputs. BootstrapVue has form controls that are commonly used like text inputs, checkboxes, files inputs, radio buttons, dropdowns, etc.
To make a simple form with BootstrapVue, we can write the following:
App.vue
:
<template>
<div id="app">
<b-form @submit.prevent="onSubmit" @reset="onReset">
<b-form-group label="Name:" description="Enter your name" id="name">
<b-form-input
id="name-group"
v-model="form.name"
type="text"
required
placeholder="Enter name"
></b-form-input>
</b-form-group>
<b-form-group id="email-group" label="Email:" label-for="email">
<b-form-input id="email" v-model="form.email" required placeholder="Enter email"></b-form-input>
</b-form-group>
<b-form-group id="fruit-group" label="Fruit:" label-for="favorite-fruit">
<b-form-select id="favorite-fruit" v-model="form.fruit" :options="fruits" required></b-form-select>
</b-form-group>
<b-form-group id="sign-up">
<b-form-checkbox-group v-model="form.choices" id="sign-up">
<b-form-checkbox value="foo">I want foo</b-form-checkbox>
<b-form-checkbox value="bar">I want bar</b-form-checkbox>
</b-form-checkbox-group>
</b-form-group>
<b-button type="submit" variant="primary">Submit</b-button>
<b-button type="reset" variant="danger">Reset</b-button>
</b-form>
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
fruits: ["apple", "orange", "banana"],
form: {}
};
},
methods: {
onSubmit(){
console.log(this.form)
},
onReset(){
alert('Form reset')
}
}
};
</script>
In the code above, we wrap our controls in the b-form-group
component, which corresponds to the form group in the plain JavaScript version of Bootstrap. Inside each b-form-group
, we have our form control. If it’s a text input, then we use the b-form-input
component. It takes the v-model
directive to bind the input value to the model.
The b-form-select
component is a dropdown. It takes the options
prop, which binds to an array of values and display them in the dropdown as the choices. v-model
binds to the selected choice.
The b-form-checkbox
component renders the checkbox control. They reside inside the b-form-checkbox-group
component, which takes the v-model
directive that binds to an array of the checked choices.
b-buttons
are render buttons. We can set the style with the variant
prop. It also takes the type
prop, which sets the type
attribute of the button.
All of them items above are wrapped inside the b-form
component. It handles the submit event and reset event just like a regular HTML form. In the code above, we have the @submit.prevent
directive to prevent the default submit action, so it’ll run onSubmit
and log the value.
The onReset
handler runs when we click Reset to reset the form.
Inline form
We can add the inline
prop on b-form
to display form controls and buttons on a single horizontal row.
For instance, we can make a form with an inline input, checkbox and button as follows:
<template>
<div id="app">
<b-form inline>
<label class="sr-only" for="name">Name</label>
<b-input-group class="mb-2 mr-sm-2 mb-sm-0">
<b-input id="name" placeholder="Name" v-model='form.name'></b-input>
</b-input-group>
<b-form-checkbox class="mb-2 mr-sm-2 mb-sm-0">Remember me</b-form-checkbox>
<b-button variant="primary">Save</b-button>
</b-form>
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
form: {}
};
}
};
</script>
All we did was add inline
to the b-form
as an attribute. Then everything inside is inline.
Form Validation Feedback
The b-form-invalid-feedback
component lets us add feedback when an invalid inputs are entered into an input. There’s also a b-form-valid-feedback
to indicate that a valid value is inputted into the input box.
For instance, we can use it as follows:
<template>
<div>
<b-form @submit.stop.prevent>
<label for="email">Email</label>
<b-input v-model="form.email" :state="validation" id="email-user"></b-input>
<b-form-invalid-feedback :state="validation">Email not valid.</b-form-invalid-feedback>
<b-form-valid-feedback :state="validation">Email is valid.</b-form-valid-feedback>
</b-form>
</div>
</template>
<script>
export default {
name: "App",
computed: {
validation(){
return /^\S+@\S+$/.test(this.form.email)
}
},
data() {
return {
form: {}
};
}
};
</script>
In the code above, we have an input which takes an email. We use a computed property to compute the validity of the inputted text to see if it’s actually an email address. This computation is done in the validation
function.
The resulting validation
computed property is set as the value of the state
prop. Then if validation
returns true
we display the b-form-valid-feedback
component. Otherwise, we display the b-form-invalid-feedback
component.
The b-input
component also takes the state
prop with the value set to validation
. The border and icon on the right changes depending if the input is valid. If validation
returns true
, which means the inputted value is valid, then the border turns green and a check mark icon is displayed. Otherwise, the border turns red and an exclamation mark icon is displayed.
If we don’t want to display any validation feedback and we have the state
prop added onto the components, we can set the value to null
.
Radio Button
We can use the b-form-group
with the b-form-radio-group
nested inside to create a group of radio buttons. b-form-radio-group
takes the options
prop which is the options for the radio button group. It also takes the v-model
directive to bind the radio value that’s selected to the model.
For example, we can add the radio button as follows:
<template>
<div>
<b-form-group label="Favorite Fruit">
<b-form-radio-group
id="radio-group"
v-model="selected"
:options="options"
name="radio"
></b-form-radio-group>
</b-form-group>
<p>{{selected}}</p>
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
selected: "apple",
options: [
{ text: "apple", value: "apple" },
{ text: "orange", value: "orange" },
{ text: "banana", value: "third", disabled: true },
{ text: "grape", value: { name: 'grape' } }
]
};
}
};
</script>
In the code above, we have an options
array with the data for the choices. The text
property will be displayed to the user as the text for each choice. The value
will be the selected value. It doesn’t matter what kind of object or value it is. As we can see, anything works.
When we click the value, we get the value selected set as the value of selected
.
Images
Bootstrap has the b-img
component for displaying images. It’s useful because it makes images responsive so they won’t be larger than their parent elements.
We can use it as follows:
<template>
<div>
<b-img
src="https://images.unsplash.com/reserve/bOvf94dPRxWu0u3QsPjF_tree.jpg?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=755&q=80"
fluid
alt="tree"
></b-img>
</div>
</template>
<script>
export default {
name: "App"
};
</script>
The code above creates a responsive image automatically. It also takes an alt
attribute like a regular img
element for accessibility.
We can also change fluid
to fluid-grow
so that the image fills the screen’s width if it’s smaller than width of the screen.
It also has a feature to round the corner of images. To make an image with rounded corners, we can add the rounded
prop to the b-img
component. If we don’t pass in any value, then all corners are rounded.
We can also set the values as follows:
true
or no value: round all corners
false
or prop not present: no rounding or corners (default)
'top'
: round the top corners
'right'
: round the right corners
'bottom'
: round the bottom corners
'left'
: round the left corners
'circle'
: make a circle (if square image) or oval (if not square) border
'0'
: turn off rounding of corners
We can make an oval image as follows:
<template>
<div>
<b-img
src="https://images.unsplash.com/reserve/bOvf94dPRxWu0u3QsPjF_tree.jpg?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=755&q=80"
fluid
rounded='circle'
alt="tree"
></b-img>
</div>
</template>
<script>
export default {
name: "App"
};
</script>
Tables
Tables are an important part of many apps. Therefore, like the regular version of Bootstrap, BootstrapVue also has a table component built in.
We can create a table by using the b-table
component. Then we don’t have to create a table from scratch. For instance, we can create a table with some data and an explicit mapping of table fields to the headings by writing:
<template>
<div>
<b-table striped hover :items="items" :fields='fields'></b-table>
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
fields: [
{ key: "firstName", label: "First" },
{ key: "lastName", label: "Last" },
"age",
],
items: [
{ age: 38, firstName: "Jane", lastName: "Smith" },
{ age: 21, firstName: "Alex", lastName: "May" },
{ age: 16, firstName: "Mary", lastName: "Jones" },
]
};
}
};
</script>
In the code above, we have the fields
object, which has the key
, which is the property names of the items
entries. The label
is the heading text of the column of the corresponding field name. So firstName
in the item from the items
entry corresponds has the First
heading. The lastName
in the item from the items
entry has the Last
heading.
Modals
Modals are also an important part of many apps. We need them to overlay the page for dialog boxes and other similar things.
BootstrapVue has the b-modal
component to make creating modal dialogs easy. We just need to set the id
prop of the b-modal
and then we use the id
name as the v-b-modal
‘s directive modifier on the element that’ll open when the element is clicked so that the element will open the modal with the id
that we set.
The title
is set so that we can set the title of the modal.
For instance, we can write the following to show the modal when a button is clicked:
<template>
<div>
<b-button v-b-modal.modal-simple>Show modal</b-button>
<b-modal id="modal-simple" title="Simple Modal">
<p>Hello!</p>
</b-modal>
</div>
</template>
<script>
export default {
name: "App"
};
</script>
In the code above, we have the v-b-modal.modal-simple
directive on the button to show the modal with the id
. Then the modal will show ‘Simple Modal’ as the title once it’s opened.
The modal also has the OK and Cancel button by default.
Conclusion
With BootstrapVue, we can create a Vue app that has styled components fast. It has components for form controls, tables, images, and many more that aren’t shown in this article. It’s easy to use and so we can get results fast.
To components also lets us write cleaner code. As we can see from the b-table
example, we didn’t have to reference the table elements at all to create a table. We just need the data and the b-table
component will map the fields to table cells.