How to Build a Modal in Vue.Js
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
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.
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-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-to, when the condition is false it will add
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:
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
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.
We imported the component in order to use it, we populated it through the slots and called its methods for opening or closing it.
Vue.js Ref attribute
ref attribute to our component
<modal ref="modalName"> so we would be able to use its methods on click
You can read more about Vue.js ref attribute here.
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.