Make a Modal using Bootstrap CSS and VueJS

The Modal will look and work like a Bootsrap Modal. But instead of using jQuery, VueJS 2.0 is used. The picture below shows the end result.

How to make a modal using Bootstrap CSS and VueJS 2

Make a Vue 2.0 project using the Vue-CLI

This tutorial is using Run-time only. Don’t forget to npm install the modules and then npm run dev.

Install Bootstrap 3 CSS

Go and grab it from the Bootstrap CDN. Copy only the the minified CSS. Do not copy the JavaScript. Again, we’ll use VueJS for that.

Open the index.html file. Place the Minified Bootstrap CSS in the <head> section.


<DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Bootstrap VueJS Modal</title>
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" type="text/css" >
  </head>
  <body>
    <div id="app"></div>
    <!-- built files will be auto injected -->
  </body>
</html>

Bootstrap 3 CSS is now installed.

Make the Modal Component

Make a Modal.vue file and save it in the components folder. It’s inside the src folder of the project.

Below is the template for this component. The HTML tags are based from Bootstrap. The CSS classes are exactly the same. But instead of using the Bootstrap fade CSS class, we use VueJS’ <transition> component. And since this is a modal, we add name="modal" attribute to <transition>. Note that this tag is new in VueJS 2.0.


<template> 
<transition name="modal">
 <div class="modal" style="display: block">
  <div class="modal-dialog" role="document">
    <div class="modal-content">
      <div class="modal-header">
        <h4 class="modal-title">
          Modal title
        </h4>
      </div>
      
      <div class="modal-body">
      </div>
      
      <div class="modal-footer">
      </div>
    </div>
  </div>
</div>
</transition> 
</template>

The outer most <div> has a style attribute to override Bootstrap’s .modal class; this is so the Modal will show up.

And this is it for now! Later on, we’ll add VueJS’s <slot> tags to make this Modal reusable.

Test the Modal Component

Open this Modal in the App.vue file. To include the Modal in the App.vue, we need to import it, register it as a component, and add it in the template.


<script>
// import it
import Modal from './components/Modal';

export default {
  // register it as a component
  components: {
    Modal
  }
}
</script> 

Below shows the <modal> component included in the <template>.


<template>
 <div id="wrapper" class="container">
   <modal></modal>
 </div>
</template>

The modal is now showing on the page:

How to make a modal using Bootstrap CSS and VueJS 2

We need a flag variable to show and hide the Modal.


<script>
export default { 
  components: { 
     Modal 
  }, 
  data() { 
    return { 
      showModal: false 
    } 
  } 
} 
</script>

The showModal flag is default to false so that the Modal doesn’t show up yet. Let’s make a button that opens the Modal.


<template>
 <div id="wrapper" class="container">
  <modal v-if="showModal"></modal> 
  <button type="button" class="btn btn-primary" @click="openModal()">Open Modal</button>
 </div>
</template>

The image below shows that the modal is how hidden and a button is added.

How to make a modal using Bootstrap CSS and VueJS 2

If you haven’t noticed, showModal is on the v-if of the <modal> component. So if showModal is false, the Modal will not show. If showModal is true, then the Modal will show. To open the Modal, we need to set showModal to true. To do this, let’s define the openModal() method.


export default { 
 components: { 
   Modal 
 }, 
 data() { 
   return { 
     showModal: false 
   } 
 }, 
 methods: { 
   openModal() { 
     this.showModal = true; 
   } 
 } 
} 
</script>

Go to the browser and test. Click the button and see the Modal open.

To close the Modal, we need to have a close button. This close button should be in the Modal. As a standard Bootstrap modal, a close button is on the footer.

Making the Modal reusable

VueJS 2.0 has the <slot> component. We can use it to inject a close button in the Modal component’s footer. Add <slot> in the Modal.vue; one in the <header>, <body>, and <footer>.


<template> 
<transition name="modal">
 <div class="modal" style="display: block">
  <div class="modal-dialog" role="document">
    <div class="modal-content">
      <div class="modal-header">
        <slot name="header"></slot>
      </div>
      
      <div class="modal-body">
        <slot name="body"></slot>
      </div>
      
      <div class="modal-footer">
        <slot name="footer"></slot>
      </div>
    </div>
  </div>
</div>
</transition> 
</template>
 

Now this Modal can have any header, body and footer content. Each <slot> has a name for designation.

Define the header and footer content

Modify <modal> in App.vue. To make sure we still have the same title as earlier, we’ll use the slot="header". Along with it, we define the footer body:


<template>
<div id="wrapper" class="container"> 
 <modal v-if="showModal"> 
  <h3 slot="header" class="modal-title">
    Modal title
  </h3>
    
  <div slot="footer">
   <button type="button" class="btn btn-outline-info" @click="closeModal()"> Close </button>
   <button type="button" class="btn btn-primary" data-dismiss="modal" @click="submitAndClose()">
     Submit
   </button>
  </div>
</modal>
. . .

I added a submit button just to elaborate.

How to make a modal using Bootstrap CSS and VueJS 2

Define the closeModal()

This method is defined in the App.vue‘s method property because it’s in the scope of App.vue. It’s not in the scope of Modal.vue component. This also means that this.showModal is in the same scope.


<script>
.  .  .
methods: {
  openModal() {
      this.showModal = true;
  },
  closeModal() {
     this.showModal = false;
  },
  submitAndClose() {
    . . .
  }
}
</script> 

Modal mask background

Most modals have a mask behind them so that the user can’t click any other buttons behind the modal. To do this, the entire modal is enclosed by this mask excluding <transition>. The CSS will be declared in the <style> section of the Modal.vue file.


<template> 
<transition name="modal">
 <div class="modal modal-mask" style="display: block">
  <div class="modal-dialog" role="document">
    <div class="modal-content">
      <div class="modal-header">
        <slot name="header"></slot>
      </div>
      
      <div class="modal-body">
        <slot name="body"></slot>
      </div>
      
      <div class="modal-footer">
        <slot name="footer"></slot>
      </div>
    </div>
  </div>
</div>
</transition> 
</template>

The CSS is defined below


<style>
.modal-mask {
  position: fixed;
  z-index: 9998;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, .5);
  display: table;
  transition: opacity .3s ease;
}
</style>

That’s it

This is a simple, basic and reusable Modal. The design and layout are exactly like a Bootstrap modal. And, it is a Bootstrap modal! It’s also 100% compatible with VueJS.

Check out the code on GitHub.