While building your application you'll definitely find yourself In situations where the user must confirm an action before proceeding, for such cases modals can be very useful, let's take for example a modal that would ask the user to confirm before deleting an item, for that we'll be using both Vuejs and TailwindCSS to build a modal component.

This component will be using props, one would be a boolean that controls the visibility of the component, the second would be the URL to which the modal will send the post request when the user click on confirm button, the body of the component would be a generic message asking the user for confirmation there is no need to specify it each time, but you can do that with props or slots.

I won't get into the details of how to create a VueJs project, you can check that in the Docs.

In this example, we're having two files the first App.vue where we will call the modal component and the second file is the component itself DeleteModal.vue.

For CSS I'm using TailwindCSS, I choose it because I like it's utility class approach, feel free to use normal CSS if you like or any other framework/library. 


//App.vue
<template>
    <div id="app" class="flex h-screen items-center justify-center">
        <button @click="showModal = true" class="bg-transparent border border-green-500 hover:border-green-500 text-gray-700 hover:text-green-500 font-bold py-2 px-4 rounded-md">
            Open Modal
        </button>

        <DeleteModal :show="showModal" submitUrl="http://localhost:8080/delete" @close="showModal=false"> </DeleteModal>
    </div>
</template>

<script>
    import DeleteModal from "./components/Modal.vue"

    export default {
        name: "App",

        components: {
            DeleteModal
        },

        data() {
            return {
                showModal: false
            }
        }
    }
</script>

Here we have a button with a click event that will set the ShowModal property to true, the same data attribute is sent to the component <DeleteModal> as a prop named show, we also send the URL that we will submit to as a prop called submitUrl.

Before using the component we must Import it and add it to the components object.

We also have a listener named @close outside the component, Once that event is emitted from inside the component we will update the ShowModal property to false.


//DeleteModal.vue
<template>
    <div v-if="show" class="modal fixed w-full h-full top-0 left-0 flex items-center justify-center">
        <div @click.self="close_modal()" class="modal-overlay absolute w-full h-full bg-gray-900 opacity-50"></div>

        <div class="modal-container bg-white w-11/12 md:max-w-md mx-auto rounded shadow-lg z-50 overflow-y-auto">

            <div @click="close_modal()" class="fas fa-times absolute top-0 right-0 cursor-pointer flex flex-col items-center mt-4 mr-4 text-white text-sm z-50"></div>

            <div class="modal-content py-4 text-left px-6">

                <div class="flex justify-between items-center pb-3">
                    <p class="text-2xl font-bold">Confirmation Modal</p>
                    <div @click="close_modal()" class="fas fa-times cursor-pointer z-50"></div>
                </div>

                <p>Canfirm the deletion of this item</p>

                <div class="flex justify-end pt-2">
                    <button @click="close_modal()" class="py-2 px-4 mr-2 rounded-md bg-transaprent text-gray-700 hover:bg-gray-700 hover:text-white border border-gray-700">
                        Cancel
                    </button>

                    <button @click="submit()" class="py-2 px-4 rounded-md bg-red-600 text-white hover:bg-white hover:text-red-600 border border-red-600">
                        Confirm
                    </button>
                </div>
            </div>
        </div>
    </div>
</template>

<script>
    export default {
        name: "DeleteModal",

        props: {
            show: Boolean,
            submitUrl: String,
        },

        methods:{
            close_modal() {
                this.$emit("close")
            },

            submit() {
                fetch(this.submitUrl).then((response) => {
                    console.log(response.json())
                }).then((data) => {
                    console.log(data)
                })
            }
        }
    }
</script>

Inside The component, we accept 2 props show a boolean property that will control the visibility of the modal. submitUrl a property of type string, where we will submit

We also have 2 methods the close_modal() and the submit()close_modal() will emit to the @close listener that we defined outside the component so it will change the showModal property to false and hide the component.submit() will send a request to the submitUrl, I used the built-in fetch method to mimic a request.