You can use bootstrap modal in vuejs without jquery or any other libraries. To do that you need to get the modal instance associated with a DOM element using the getInstance method.
const ItemModal = document.getElementById("ItemModal");
const modal = bootstrap.Modal.getInstance(ItemModal);
Recently I was revamping a user profile page made with bootstrap and jQuery. I got stuck on this problem that Bootstrap modals didn’t work with vuejs.
I didn’t wanted to use bootstrap-vue because I wanted to keep code changes to minimum and use existing code.
On this short tutorial, I’ll show how to use getInstance method to control bootstrap modal. We will be developing a simple shopping list app using bootstrap modals for add/edit functionality.
Starting point
To make things simple I’m using cdn scripts for vuejs and bootstrap. If you are using a build tools you can view other installation methods on vuejs.org
On index page we are including bootstrap js/css and vuejs cdn in the header. Then we are adding a simple table and a button to add items. On next steps we will be hook this up with vuejs.
<!-- ./index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue bootstrap modal</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC"
crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js"
integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM"
crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<div id="app">
<nav class="navbar navbar-light bg-light">
<div class="container-fluid">
<span class="navbar-brand mb-0 h1">Shopping list</span>
<button class="btn btn-outline-success" type="button">Add
Item</button>
</div>
</nav>
<div class="container my-3">
<div class="row">
<div class="col-md-12">
<table class="table">
<th>Item</th>
<th>Qty</th>
</table>
</div>
</div>
</div>
</div>
</body>
</html>
initialize vue
we are creating a vuejs instance and attaching it to the DOM element app . inside data object we are creating two properties, empty array to store items and empty item object to hold current item.
new Vue({
el: "#app",
data: {
item: {
},
itemArr: [],
},
methods: {
},
});
we are adding a script tag on index.html before closing body to refer app.js
<script src="./app.js"></script>
</body>
</html>
create model
Following code creates the model with simple form to add items. v-model directive binds inputs with vuejs data object. we are using v-on:click ( @click ) directive to listen button click event. place the code inside app element
<div id="app">
<nav class="navbar navbar-light bg-light">
<div class="container-fluid">
<span class="navbar-brand mb-0 h1">Shopping list</span>
<button @click="openItemModal" class="btn btn-outline-success" type="button">Add
Item</button>
</div>
</nav>
<div class="container my-3">
<!-- ... -->
</div>
<div class="modal fade" id="itemModal" tabindex="-1" aria-labelledby="itemModalLabel"
aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<form @submit.prevent="addItem">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Shopping item
</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"
aria-label="Close"></button>
</div>
<div class="modal-body">
<div class="mb-3">
<label for="itemName" class="form-label">Item
name</label>
<input v-model="item.name" type="text"
class="form-control" id="itemName" required>
</div>
<div class="mb-3">
<label for="qty" class="form-label">QTY</label>
<input v-model="item.qty" type="number"
class="form-control" id="qty" min="0" required>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary"
data-bs-dismiss="modal">Cancel</button>
<button type="submit" class="btn btn-primary">Add</button>
</div>
</form>
</div>
</div>
</div>
</div>

Inside app.js create the openItemModal method
methods: {
openItemModal(){
const ItemModal = document.getElementById("itemModal");
const modal = bootstrap.Modal.getOrCreateInstance(ItemModal);
modal.show();
},
// ...
we are creating a modal instance here using getOrCreateInstance . because modal instance is not yet created. and then we are showing the modal.
Add item
To add an item you need to get item object and push it into the itemArr. Note that we have bind the html inputs with item object. We make item object empty and hide the model. we are using getInstance here since bootstrap modal is already created.
addItem() {
this.itemArr.push({ ...this.Item });
this.item = {};
const ItemModal = document.getElementById("itemModal");
const modal = bootstrap.Modal.getInstance(ItemModal);
modal.hide();
}
Display items list
Using v-for directive we can render the itemArr in the table body. we are using array index as the key.
<table class="table">
<thead>
<th>Item</th>
<th>Qty</th>
</thead>
<tbody>
<tr v-for="(item,index) in itemArr" :key="index">
<td>{{item.name}}</td>
<td>{{item.qty}}</td>
</tr>
</tbody>
</table>
Edit & Remove item
Let’s quickly add two buttons for Edit and Remove items in table.
<table class="table">
<thead>
<th>Item</th>
<th>Qty</th>
<th width="25%"></th>
</thead>
<tbody>
<tr v-for="(item,index) in itemArr" :key="index">
<td>{{item.name}}</td>
<td>{{item.qty}}</td>
<td>
<button @click="editItem(item)" class="btn btn-primary">Edit</button>
<button @click="removeItem(index)" class="btn btn-danger">X</button>
</td>
</tr>
</tbody>
</table>

Here we are using @click directive as we used before. we are passing the item object with editItem event . for the removeItem we are passing the array index.
Let’s create editItem and removeItem methods inside app.js
on editItem we get the item assign to item object and remove it from itemsArr . on removeItem we just remove the item from itemsArr. to remove the item we are using splice and indexOf javascript methods.
editItem(item) {
this.item = item;
this.itemArr.splice(this.itemArr.indexOf(item), 1);
const ItemModal = document.getElementById("itemModal");
const modal = bootstrap.Modal.getInstance(ItemModal);
modal.show();
},
removeItem(item){
this.itemArr.splice(this.itemArr.indexOf(item), 1);
}
We have completed our Shopping list application !!!
Hope you understand how to use vuejs to develop CRUD application with bootstrap modals.
If you have any questions let me know in comments section. Cheers..