Modal

Reference

v-modelundefined
Boolean
Set the v-model to true to show modal or false to hide it.

backdrop
(attributes)
{}
Object
Attributes of the v-backdrop component

base"modal"
String
Base name used to style component

close-button
(attributes)
{}
Object
Attributes of the v-close-button component. See documentation for the valid values

justify-buttons"end"
String
Use this prop to place buttons in the footer. Valid values are: 'start', 'end', 'center', 'between', 'around', 'evenly'

mod-contentempty string
String
Style of the content part of modal element

mod-footerempty string
String
Style of the modal footer element

mod-headerempty string
String
Style of the modal header element

mod-modalempty string
String
Style of the main modal element

nameempty string
String
Name of the component

no-close-buttonfalse
Boolean
Disables the 'X' button in modal header

no-footerfalse
Boolean
Do not render the footer if true

no-headerfalse
Boolean
Do not render the header if true

no-primary-buttonfalse
Boolean
Disables primary (OK) button

no-secondary-buttonfalse
Boolean
Disables secondary (Cancel) button

position"top"
String
Position of the modal. Valid values are: 'top', 'center' or 'bottom'

primary-button
(attributes)
{ "modButton": "variant:primary" }
Object
Attributes of the primary v-button component. See documentation for the valid values

primary-button-closefalse
Boolean
If true clicking primary button emits the input:secondaryButtonClick event and closes modal. If false modal is not closed after emitting event

primary-button-label"Accept"
String
Label of the primary button

secondary-button
(attributes)
{ "modButton": "variant:secondary" }
Object
Attributes of the secondary v-button component. See documentation for the valid values

secondary-button-closefalse
Boolean
If true clicking primary button emits the input:primaryButtonClick event and closes modal. If false modal is not closed after emitting event

secondary-button-label"Close"
String
Label of the secondary button

size"md"
String
Size of the modal on medium and larger screens. Valid values are: 'sm', 'md', 'lg', 'xl' or 'fit'

static-backdropfalse
Boolean
If true modal dialog cannot be closed by clicking outside of it

titleundefined
String
Title displayed in the modals header

transition"fade-slide"
String
Sets the animation effect when showing or hiding modal. Valid values are: 'fade', 'fade-slide', 'fade-scale' or empty string to disable animations. Animation speed can be set in the --modal-transition-duration css variable.

variantempty string
String
Active variant of the element mod-* props
Events
input:primary-button-click
Emmited after clicking primary button

input:secondary-button-click
Emmited after clicking secondary button

update:modelValue
Updates v-model of component

input:static-backdrop-click
Emmited after clicking backdrop if the static-backdrop prop is true
Slots
modal
Swaps the entire default content of the v-modal. Slot props: close()

header
Modal header content

default
Modal content

footer
Modal footer content

Notes

To control modal visibility you can use v-model or v-trigger component

Teleport

Open modal is by default appended to the body element


Example - simple modal

    <template>
  <v-button @click="isVisible = !isVisible">Show modal</v-button>

  <v-modal
    v-model="isVisible"
    title="Simple modal"
    primary-button-close
    secondary-button-close
  >
    Simple modal it is.
  </v-modal>
</template>
  
    <script setup>
import { ref } from "vue";

let isVisible = ref(false);
</script>
  

Example - props

top
sm
fade-slide
    <template>
  <div class="flex gap-x-4 w-full">
    <v-button @click="state.isVisible = !state.isVisible">Show modal</v-button>
    <v-button @click="state.isVisibleLong = !state.isVisibleLong">
      Show long scrollable modal
    </v-button>
  </div>


  <!-- modal -->

  <v-modal
    v-model="state.isVisible"
    v-bind="example"
  >
    <!-- forms -->

  </v-modal>

  <!-- long scrollable modal -->

  <v-modal
    v-model="state.isVisibleLong"
    v-bind="example"
  >
    {{ longText[0] }}
  </v-modal>
</template>
  
    <script setup>
import { ref, reactive } from "vue";
import { longText } from "../example-data/data.js";

let example = reactive({
  title: "Example modal",
  noPrimaryButton: false,
  noSecondaryButton: false,
  primaryButtonLabel: "OK",
  secondaryButtonLabel: "Cancel",
  primaryButtonClose: false,
  secondaryButtonClose: true,
  justifyButtons: "end",
  noCloseButton: false,
  staticBackdrop: false,
  noHeader: false,
  noFooter: false,
  position: "top",
  size: "sm",
  transition: "fade-slide",
});

let state = reactive({
  isVisible: false,
  isVisibleLong: false,
  isVisibleImage: false,
});

let images = ["mononoke035.jpg", "mononoke033.jpg"];

let currentImage = ref(0);

let next = () => {
  return (currentImage.value =
    currentImage.value + 1 > 1 ? 0 : currentImage.value + 1);
};

let prev = () => {
  return (currentImage.value =
    currentImage.value - 1 < 0 ? 1 : currentImage.value - 1);
};
</script>
  

Example - modal slot

Following example uses modal slot to replace all default content for complete customization.

    <template>
  <v-button @click="isVisible = !isVisible">Show customized modal</v-button>

  <v-modal
    v-model="isVisible"
    size="fit"
    mod-modal="shape:square"
    :backdrop="{ modBackdrop: 'filter:blur' }"
  >
    <template #modal="{ close }">
      <div class="group">
        <img
          :src="'/assets/' + images[currentImage]"
          width="1000"
          alt=""
        />
        <v-close-button
          class="absolute top-5 right-5"
          @click="close()"
        />

        <!-- thumbnails -->

        <div class="absolute bottom-0 w-full flex justify-center gap-x-4 p-2">
          <img
            v-for="(image, index) in images"
            :src="'/assets/' + image"
            width="110"
            alt=""
            :class="{
              'ring-4 ring-indigo-500': image === images[currentImage],
            }"
            class="opacity-0 group-hover:opacity-100 transition-opacity shadow-md shadow-black/30 hover:scale-105 duration-300 cursor-pointer"
            @click="currentImage = index"
          />
        </div>

        <!-- prev and next buttons -->

        <v-button
          @click="prev()"
          mod-button="preset:plain"
          class="absolute -translate-y-1/2 top-1/2 left-5 duration-300 transition-opacity text-white opacity-0 group-hover:opacity-80"
        >
          <v-icon
            name="fa-chevron-left-solid"
            class="w-12 h-12"
          ></v-icon>
        </v-button>
        <v-button
          @click="next()"
          mod-button="preset:plain"
          class="absolute -translate-y-1/2 top-1/2 right-5 duration-300 transition-opacity text-white opacity-0 group-hover:opacity-80"
        >
          <v-icon
            name="fa-chevron-right-solid"
            class="w-12 h-12"
          ></v-icon>
        </v-button>
      </div>
    </template>
  </v-modal>
</template>
  
    <script setup>
import { ref } from "vue";

let isVisible = ref(false);

let images = ["mononoke035.jpg", "mononoke033.jpg"];

let currentImage = ref(0);

let next = () => {
  return (currentImage.value =
    currentImage.value + 1 > 1 ? 0 : currentImage.value + 1);
};

let prev = () => {
  return (currentImage.value =
    currentImage.value - 1 < 0 ? 1 : currentImage.value - 1);
};
</script>
  

Example - open by id

You can also control state of the modal by using v-trigger component. The for prop of the v-trigger should be the same as id of the modal. v-trigger can be anywhere in application.

    <template>
  <v-trigger for="modal" v-slot="{ onTrigger }">
    <v-button v-on="onTrigger">Show modal</v-button>
  </v-trigger>

  <v-modal id="modal" title="Trigger modal">Trigger modal</v-modal>
</template>
  

Example - backdrop

To configure colors, intensity and others properties of modals backdrop use backdrop prop. See backdrop documentation for possible options.

    <template>
  <v-button @click="isVisible = !isVisible">Show modal with less boring backdrop</v-button>

  <v-modal
    v-model="isVisible"
    title="Simple modal"
    :backdrop="{ modBackdrop: 'variant:gradient' }"
    primary-button-close
    secondary-button-close
  >
    Simple modal it is.
  </v-modal>
</template>
  
    <script setup>
import { ref } from "vue";

let isVisible = ref(false);
</script>