Create Reusable VueJs Popup Modal

Quickly and easily create beautiful, reusable Vuejs popup modals. With just a few lines of code, you can easily customize your popup to fit the needs of any project. This post will take you through building a simple popup modal in Vuejs with a slot.

Create Vuejs popup modal component

We used the prop value to show or hide the popup modal directly with the v-if condition of Vuejs. The close “x” button will emit input to false which will update the value to false and close the popup modal.

In ./src/components/PopupModal.vue

<template>
  <div v-if="isShow" class="popup-modal animate">
    <div class="popup-modal__wrapper">
      <span @click="$emit('input', false)" class="close">X</span>
      <div class="content">
        <slot></slot>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  props: {
    value: {
      required: true,
      type: Boolean,
    },
  },
  computed: {
    isShow: {
      get() {
        return this.value;
      },
      set(val) {
        this.$emit('input', val);
      },
    },
  },
};
</script>

<style lang="scss" scoped>
.popup-modal {
  width: 100vw;
  height: 100vh;
  position: fixed;
  z-index: 99999;
  top: 0;
  left: 0;
  background: rgba($color: #000000, $alpha: 0.1);
  display: flex;
  justify-content: center;
  align-items: center;

  &__wrapper {
    width: 800px;
    height: 600px;
    background-color: white;
    border-radius: 6px;

    .close {
      float: right;
      padding: 6px;
      cursor: pointer;
    }

    .content {
      width: 100%;
      height: 100%;
    }
  }
}

.animate {
  -webkit-animation: fadeIn 1s;
  animation: fadeIn 1s;
}

@-webkit-keyframes fadeIn {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

@keyframes fadeIn {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
</style>

Use custom popup modal component

In this sample usage of the popup modal, we will import and use the component directly. The v-model here is what told the popup modal component to show or not based on the value true or false.

In ./src/pages/HelloWorld.vue

<template>
  <div>
    <button @click="popupModal = true">Show popup modal</button>
    <popup-modal v-model="popupModal">
      <div
        style="
          height: 100%;
          display: flex;
          justify-content: center;
          align-items: center;
        "
      >
        <span>Test</span>
      </div>
    </popup-modal>
  </div>
</template>

<script>
import PopupModal from '@/components/PopupModal.vue';

export default {
  components: {
    PopupModal,
  },
  data() {
    return {
      popupModal: false,
    };
  },
};
</script>

Declare component globally

If the component is used frequently you can declare it as a global component like below.

In ./src/main.js

import Vue from 'vue';
import App from './App.vue';
import router from './routes';
import PopupModal from '@/components/PopupModal';

Vue.config.productionTip = false;

Vue.component('popup-modal', PopupModal);

new Vue({
  router,
  render: (h) => h(App),
}).$mount('#app');

And use directly without importing the component.

<template>
  <div>
    <button @click="popupModal = true">Show popup modal</button>
    <popup-modal v-model="popupModal">
      <div
        style="
          height: 100%;
          display: flex;
          justify-content: center;
          align-items: center;
        "
      >
        <span>Test</span>
      </div>
    </popup-modal>
  </div>
</template>

<script>
export default {
  data() {
    return {
      popupModal: false,
    };
  },
};
</script>

Note: To compile style lang SCSS in Vue it required two dependencies

"node-sass": "^7.0.1",
"sass-loader": "^12.6.0"

It's you have any errors related to SCSS please install the above dependencies

npm install node-sass sass-loader --save-dev