vue-universal-modal
A light Universal modal Component for Vue 3.
Introduction
vue-universal-modal plugin is based on the teleport.
It is very light and simple, but it provides essential features for modal use in applications.
(Such as Add & Remove, Visible & Hidden, Transition, Auto bind keyboard and mouse to close, Support SSR, A11Y…)
Here is the Demo
Features
Based on the teleport
Provides essential features for modal
A11Y
Support SSR (Insert rendering source into SSR context, Mount from Client-side)
Install plugin
npm install vue-universal-modal
Insert teleport element in your html
…
<div id=”app”></div>
<!– teleport target –>
<div id=”modals”></div>
…
Because SSR cannot be implemented by dynamically creating and ref referencing teleport elements, teleport targets must be inserted into html first.
And install plugin in vue application
import ‘vue-universal-modal/dist/index.css’
import VueUniversalModal from ‘vue-universal-modal’
app.use(VueUniversalModal, {
teleportTarget: ‘#modals’
})
Options
app.use(VueUniversalModal, {
teleportTarget: ‘#my-modals’,
modalComponent: ‘MyModal’,
})
name
type
detault
description
teleportTarget (required)
string
modalComponent
string
‘Modal’
Global modal component name
Usage modal
Insert the component wrapped with the modal component. (Slot based)
<template>
<p>
<button @click=”showModal”>
Show modal
</button>
</p>
<!– If the option changed modal component the name
<MyModal>
–>
<Modal
v-model=”isShow”
:close=”closeModal”
>
<div class=”modal”>
<p>
Hello
</p>
<button @click=”closeModal”>
close
</button>
</div>
</Modal>
</template>
<script lang=”ts”>
import { defineComponent, ref } from ‘vue’
export default defineComponent({
setup () {
const isShow = ref(false)
function showModal () {
isShow.value = true
}
function closeModal () {
isShow.value = false
}
return {
isShow,
showModal,
closeModal
}
}
})
</script>
<style scoped lang=”scss”>
.modal {
width: 300px;
padding: 30px;
box-sizing: border-box;
background-color: #fff;
font-size: 20px;
text-align: center;
}
</style>
v1.0.x -> v1.1.x change point
Use v-model instead of v-if for modal component insertion
If you control the insertion of components with v-if, the close animation will not work.
emitClose slot argument was deprecated.
props
name
type
detault
description
close
function
() => {}
Function to close a modal (apply when click dimmed)
disabled
boolean
false
Handle just visibility (as in v-show)
options
object
{}
props.options
name
type
detault
description
transition
number | false
300
transition duration
closeClickDimmed
boolean
true
Closes the modal when dimmed is clicked
closeKeyCode
number | false
27 (esc)
Closes the modal when press key
styleModalContent
object
{}
Inject modal content style (.vue-universal-modal-content)
emit events
Supports emit properties for all transition events.
<template>
<p>
<button @click=”showModal”>
Show modal
</button>
</p>
<Modal
v-model=”isShow”
:close=”closeModal”
@before-enter=”beforeEnter”
@after-enter=”afterEnter”
@before-leave=”beforeLeave”
@after-leave=”afterLeave”
>
<div class=”modal”>
<p>
Hello
</p>
<button @click=”closeModal”>
close
</button>
</div>
</Modal>
</template>
<script lang=”ts”>
import { defineComponent, ref } from ‘vue’
export default defineComponent({
setup () {
const isShow = ref(false)
function showModal () {
isShow.value = true
}
function closeModal () {
isShow.value = false
}
function beforeEnter () {
console.log(‘before enter’)
}
function afterEnter () {
console.log(‘after enter’)
}
function beforeLeave () {
console.log(‘before leave’)
}
function afterLeave () {
console.log(‘after leave’)
}
return {
isShow,
showModal,
closeModal,
beforeEnter,
afterEnter,
beforeLeave,
afterLeave
}
}
})
</script>
Handle global CSS
You can change it directly to your own style by referring to the source
.vue-universal-modal {
/* Change dimmed color */
background-color: rgba(255, 255, 0, 0.3);
}
.vue-universal-modal-content {
/* Align to top (flex-direction property value is set to column) */
justify-content: flex-start;
}