Vue Final Modal
Vue Final Modal is a highly optimized and lightweight modal library specifically designed for Vue 3 applications, providing robust dialog, popup, and overlay functionalities. The current stable version is 4.5.5, with an active beta development for version 5.0.0, indicating a consistent release cadence with a focus on ongoing improvements and new features. Key differentiators include its balance of power and lightweight footprint, extensive customization options, and strong TypeScript support, making it suitable for complex UIs while maintaining performance. It handles common modal concerns like accessibility, scroll locking, and stacking contexts effectively, providing a comprehensive solution for interactive overlays in Vue 3 projects.
Common errors
-
The requested module 'vue-final-modal' does not provide an export named 'VueFinalModal'
cause Attempting to import `VueFinalModal` as a default export or using an incorrect named import.fixChange your import statement to `import { VueFinalModal } from 'vue-final-modal'`. -
Cannot read properties of undefined (reading 'open') when using useModal
cause `ModalsContainer` component is not present in the application's template.fixAdd `<ModalsContainer />` to your root `App.vue` or parent layout component where programmatic modals should render. -
Property 'modalId' does not exist on type 'VfmModal'
cause Attempting to access properties like `modalId` on the `useModal` instance directly when it might not be immediately available or typed correctly in all contexts.fixAccess properties like `modalId` from the modal instance returned by `open()` or ensure correct type inference for dynamically created modals, especially if you're passing custom props.
Warnings
- breaking Migration from v3 to v4 involved significant API changes. Direct upgrades without consulting the migration guide will likely result in breaking applications.
- breaking Version 5.0.0 (currently in beta) replaces `body-scroll-lock` with `scroll-lock` as a dependency. While this might be a minor change for most users, direct usage or assumptions about the underlying scroll-lock mechanism might require updates.
- gotcha When using `useModal` for programmatic modals, the `ModalsContainer` component *must* be mounted somewhere in your application. Without it, programmatic modals will not render.
- gotcha Ensure proper focus management and keyboard accessibility. While `vue-final-modal` integrates `focus-trap`, custom content within modals might interfere or require additional `aria` attributes for screen readers.
- gotcha Incorrectly applying CSS transitions or animations can lead to unexpected visual glitches or modals not appearing/disappearing smoothly. Ensure your transition classes are correctly configured.
Install
-
npm install vue-final-modal -
yarn add vue-final-modal -
pnpm add vue-final-modal
Imports
- VueFinalModal
import VueFinalModal from 'vue-final-modal'
import { VueFinalModal } from 'vue-final-modal' - useModal
import { UseModal } from 'vue-final-modal'import { useModal } from 'vue-final-modal' - ModalsContainer
import { ModalsContainer } from 'vue-final-modal'
Quickstart
import { createApp, ref } from 'vue'
import { VueFinalModal, useModal, ModalsContainer } from 'vue-final-modal'
const app = createApp({
template: `
<button @click="openModal">Open Modal</button>
<VueFinalModal
v-model="showModal"
classes="flex justify-center items-center"
content-class="relative flex flex-col max-h-full mx-4 p-4 border dark:border-gray-800 rounded bg-white dark:bg-gray-900"
:overlay-transition="'vfm-fade'"
:content-transition="'vfm-slide-up'"
@before-close="beforeClose"
>
<h1 class="text-xl">Hello, Vue Final Modal!</h1>
<p>This is a custom modal opened via a ref.</p>
<button class="mt-4 p-2 bg-blue-500 text-white rounded" @click="showModal = false">Close</button>
</VueFinalModal>
<button @click="openProgrammaticModal">Open Programmatic Modal</button>
<ModalsContainer />
`,
setup() {
const showModal = ref(false)
const { open, close } = useModal({
component: VueFinalModal,
attrs: {
title: 'Programmatic Modal',
onUpdateModelValue: (val) => console.log('Programmatic modal v-model:', val)
},
slots: {
default: '<p>This modal was opened programmatically!</p><button @click="options.close">Close</button>'
}
})
function openModal() {
showModal.value = true
}
function beforeClose() {
console.log('Modal is about to close')
// You can prevent closing here if needed
// return false
}
function openProgrammaticModal() {
open()
}
return { showModal, openModal, beforeClose, openProgrammaticModal }
}
})
app.component('VueFinalModal', VueFinalModal)
app.mount('#app')