How to Build a Modal in Vue.Js

A great way to create a simple modal from scratch

Luca Spezzano
May 4, 2020 · 4 min read
Vue.js simple modal

Modals are one of the most used components in the UI, we can find them in the most popular CSS frameworks like Bootstrap or libraries of UI components like TailwindUI.

They are useful because in our projects we often want to show messages or we need to allow users to make an action without to change page.

Usually, I used Bootstrap modals on my projects but when I changed job I started to work with Vue.js and TailwindCSS and one of my first tasks was to create a modal component.

So I started some research, I found many examples and packages which were doing that, but these did not cover all the cases, some of the most common problems were:

  • when the modal was very high it was cut
  • when the modal was open, the body of the page was still scrollable
  • they did not give to the parent the possibility to customize the content of the modal
  • they didn’t give explicit methods to trigger some events on the opening and closing actions

Today we are going to build a modal component that should be fine for every need, it will fix the problems above:

  • it will fit the page according to its content and it will become scrollable automatically
  • when the modal is open, the body of the page will not be scrollable
  • the parent will be free to customize the component adding also HTML
  • there are closeModal() and openModal() events that will give you the opportunity to trigger other events.

Building the modal

In the example below I will not use any style except the one needed for the functionality of the modal, in this way it can easily be adapted to your project.

You can see the final version with a bit of style to make it more friendly here.

Let’s start directly from the component.

Modal.vue

Let’s see what is doing the code explaining things that in my opinion need to be seen carefully.

The first tag that you can see is <transition name="fade">. This component is provided by Vue.js, it works with v-show and v-if and it automatically adds some class on this component. If you call it fade, when the condition is true, it will add for a moment the classes fade-enter-active and fade-enter-to, when the condition is false it will add fade-leave-active and fade-leave-to. With these classes we are able to customize the animations for our modal.

You can read more about Vue.js transitions here.

As you can see we used three slots: header, body, footer

Why did we use slots? They allow the parent to add HTML and that means that the parent will be free to customize the component.

You can read more about Vue.js slots here.

We could change just the value of show to toggle the modal, but we know that sometimes we need to do more stuff, that’s why we created two specific methods closeModal() and openModal(), they will simply change the value of show but in this way they are accessible and allow us to trigger other events if we need it.

In our methods you can see that we are manipulating the DOM, we know that in Vue.js this is considered a bad practice but as long as you understand exactly what you’re doing and you don’t overuse, it can be fine.

That’s all for this component, now let’s see what will happen to the parent where this component would be used.

App.vue

We imported the component in order to use it, we populated it through the slots and called its methods for opening or closing it.

The ref attribute allows us to have direct access to child components in JavaScript. We assign the ref attribute to our component <modal ref="modalName"> so we would be able to use its methods on click @click="$refs.modalName.openModal()"

You can read more about Vue.js ref attribute here.

Conclusions

Many times when we start to develop something like a component, we think that the best and the fastest solution is to use external packages or copy and paste some snippets. But is it really faster? Probably, at first yes, but when we start to use the component around our project with different needs, for sure it will cause many problems that will make us waste a lot of time.

Sometimes the best solution to create a reusable component is to create it from scratch even if it may seem the longest solution at first.

See the demo

This publication includes original articles and tips about…

By NotOnlyCSS

Articles and tips for frontend developers Take a look.

By signing up, you will create a Medium account if you don’t already have one. Review our Privacy Policy for more information about our privacy practices.

Check your inbox
Medium sent you an email at to complete your subscription.

Luca Spezzano

Written by

Frontend developer focused on CSS architecture of scalable and maintainable large scale projects and the development of amazing user interfaces.

NotOnlyCSS

This publication includes original articles and tips about frontend technologies.

Luca Spezzano

Written by

Frontend developer focused on CSS architecture of scalable and maintainable large scale projects and the development of amazing user interfaces.

NotOnlyCSS

This publication includes original articles and tips about frontend technologies.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store