How to start with Vue Final Modal, by creating a fresh new project or adding it to your Vue application.
You can start playing with Vue Final Modal in your browser using our online sandboxes:
Play in Vue 3 on StackBlitz Play in Nuxt 3 on StackBlitzyarn yarn add vue-final-modal
Copy to clipboard npm npm install vue-final-modal
Copy to clipboard pnpm pnpm add vue-final-modal
Copy to clipboard In vue-final-modal 4, it's necessary to create a plugin by createVfm ()
and register it because vue-final-modal 4 has some shared context that is based on provide/inject.
main.ts import { createApp } from 'vue'
import { createVfm } from 'vue-final-modal'
import App from './App.vue'
const app = createApp (App)
const vfm = createVfm ()
app. use (vfm). mount ( '#app' )
Copy to clipboard ./plugins/vue-final-modal.ts import { createVfm } from 'vue-final-modal'
export default defineNuxtPlugin (( nuxtApp ) => {
const vfm = createVfm () as any
nuxtApp.vueApp. use (vfm)
})
Copy to clipboard vue-final-modal 4 has tiny size of required CSS (gzipped 0.49kb). All classes have a .vfm-
prefix, so you don't have to worry about any CSS pollution.
main.ts import 'vue-final-modal/style.css'
Copy to clipboard ./nuxt.config.ts export default defineNuxtConfig ({
css: [ 'vue-final-modal/style.css' ],
})
Copy to clipboard <ModalsContainer>
is a container for the dynamic modals that created by useModal()
.
You don't need to do add anything else to the < ModalsContainer >
, as long as you include it in your Vue tree, you can use Dynamic modals.
You only need to put it once in your Vue app.
App.vue < script setup lang = "ts" >
import { ModalsContainer } from 'vue-final-modal'
</ script >
< template >
< div >
...
< ModalsContainer />
</ div >
</ template >
Copy to clipboard layouts/default.vue < script setup lang = "ts" >
import { ModalsContainer } from 'vue-final-modal'
</ script >
< template >
< div >
Some default layout shared across all pages
< slot / >
< ModalsContainer />
</ div >
</ template >
Copy to clipboard Define a styled modal for yourself. Here will create a styled < ModalConfirm >
with < VueFinalModal >
as an example.
Use plain CSS to define a < ModalConfirmPlainCss >
component with < VueFinalModal >
.
Basic examplePreview.vue < script setup lang = "ts" >
import { ModalsContainer, useModal } from 'vue-final-modal'
import ModalConfirmPlainCss from './ModalConfirmPlainCss.vue'
const { open , close } = useModal ({
component: ModalConfirmPlainCss,
attrs: {
title: 'Hello World!' ,
onConfirm () {
close ()
},
},
slots: {
default: '<p>The content of the modal</p>' ,
},
})
</ script >
< template >
< VButton @click = "open" >
Open Modal
</ VButton >
< ModalsContainer />
</ template >
Copy to clipboard ModalConfirmPlainCss.vue < script setup lang = "ts" >
import { VueFinalModal } from 'vue-final-modal'
defineProps <{
title ?: string
}>()
const emit = defineEmits <{
( e : 'confirm' ) : void
}>()
</ script >
< template >
< VueFinalModal
class = "confirm-modal"
content-class = "confirm-modal-content"
overlay-transition = "vfm-fade"
content-transition = "vfm-fade"
>
< h1 >{{ title }}</ h1 >
< slot / >
< button @click = "emit('confirm')" >
Confirm
</ button >
</ VueFinalModal >
</ template >
< style >
.confirm-modal {
display : flex ;
justify-content : center ;
align-items : center ;
}
.confirm-modal-content {
display : flex ;
flex-direction : column ;
padding : 1 rem ;
background : #fff ;
border-radius : 0.5 rem ;
}
.confirm-modal-content > * + * {
margin : 0.5 rem 0 ;
}
.confirm-modal-content h1 {
font-size : 1.375 rem ;
}
.confirm-modal-content button {
margin : 0.25 rem 0 0 auto ;
padding : 0 8 px ;
border : 1 px solid ;
border-radius : 0.5 rem ;
}
.dark .confirm-modal-content {
background : #000 ;
}
</ style >
Copy to clipboard Highly recommended to use TailwindCSS, WindiCSS or UnoCSS to define your modals.
Let's take TailwindCSS for example to define a < ModalConfirm >
component with < VueFinalModal >
.
Basic examplePreview.vue < script setup lang = "ts" >
import { ModalsContainer, useModal } from 'vue-final-modal'
import ModalConfirm from './ModalConfirm.vue'
const { open , close } = useModal ({
component: ModalConfirm,
attrs: {
title: 'Hello World!' ,
onConfirm () {
close ()
},
},
slots: {
default: '<p>UseModal: The content of the modal</p>' ,
},
})
</ script >
< template >
< VButton @click = "() => open()" >
Open Modal
</ VButton >
< ModalsContainer />
</ template >
Copy to clipboard ModalConfirm.vue < script setup lang = "ts" >
import { VueFinalModal } from 'vue-final-modal'
defineProps <{
title ?: string
}>()
const emit = defineEmits <{
( e : 'confirm' ) : void
}>()
</ script >
< template >
< VueFinalModal
class = "flex justify-center items-center"
content-class = "flex flex-col max-w-xl mx-4 p-4 bg-white dark:bg-gray-900 border dark:border-gray-700 rounded-lg space-y-2"
>
< h1 class = "text-xl" >
{{ title }}
</ h1 >
< slot / >
< button class = "mt-1 ml-auto px-2 border rounded-lg" @click = "emit('confirm')" >
Confirm
</ button >
</ VueFinalModal >
</ template >
Copy to clipboard There are three ways to control a modal component.
Take the < ModalConfirm >
component we built on previous section as an example:
useModal ()
is a composable function that is used to create a dynamic modal, then you can control the modal programmatically.
As a requirement to using useModal ()
you must add <ModalsContainer> to your main App.vue
file.
Basic examplePreview.vue < script setup lang = "ts" >
import { ModalsContainer, useModal } from 'vue-final-modal'
import ModalConfirm from './ModalConfirm.vue'
const { open , close } = useModal ({
component: ModalConfirm,
attrs: {
title: 'Hello World!' ,
onConfirm () {
close ()
},
},
slots: {
default: '<p>UseModal: The content of the modal</p>' ,
},
})
</ script >
< template >
< VButton @click = "() => open()" >
Open Modal
</ VButton >
< ModalsContainer />
</ template >
Copy to clipboard Use v-model
for show/hide a modal.
Basic examplePreview.vue < script setup lang = "ts" >
const show = ref ( false )
function confirm () {
show.value = false
}
</ script >
< template >
< VButton @click = "show = true" >
Open Modal
</ VButton >
< ModalConfirm
v-model = "show"
title = "Hello World!"
@confirm = "() => confirm()"
>
< p >VModel: The content of the modal</ p >
</ ModalConfirm >
</ template >
Copy to clipboard modelValue
is not a required prop for < VueFinalModal >
. Without using v - model
, you can also use useVfm() composable function to control the modal by given a modalId .
Basic examplePreview.vue < script setup lang = "ts" >
import { useVfm } from 'vue-final-modal'
const vfm = useVfm ()
const modalId = Symbol ( 'modalId' )
function confirm () {
vfm. close (modalId)
}
</ script >
< template >
< VButton @click = "() => vfm.open(modalId)" >
Open Modal
</ VButton >
< ModalConfirm
:modal-id = "modalId"
title = "Hello World!"
@confirm = "() => confirm()"
>
< p >The content of the modal</ p >
</ ModalConfirm >
</ template >
Copy to clipboard