A lib for dealing with modal without having to defining it locally it into your components and handling its visualization with a boolean flag.
You just need to:
- add the plugin
- add the
<Modals/>
component into your root component (aka<App/>
) - create a component for your modal*
- "open" your modal component
⚠️ Vue 3 only!
⚠️ CSS not included.* read Modal API before using, don't "GO HORSE"
import { createApp } from 'vue';
import Modals from 'vue-modal4real';
import App from '@/App.vue';
createApp(App)
.use(Modals)
.mount('#app');
<template>
...
<Modals/>
</template>
<script setup>
import { useModals } from 'vue-modal4real';
import MyModal from '@/components/MyModal';
const modals = useModals();
function openModal() {
modals.open(MyModal);
}
</script>
<template>
<button @click="openModal">Open Modal</button>
</template>
<template>
<button @click="openModal">Open Modal</button>
</template>
<script>
import { useModals } from 'vue-modal4real';
import MyModal from '@/components/MyModal';
export default {
name: 'App',
methods: {
openModal() {
this.$modals.open(MyModal);
}
}
}
</script>
In order to use a component as a Modal you only have one mandatory new config to use.
Define two emits for your component: "resolve" and "reject".
Those two new emits is how you close your modal, yes it's Promise
.
<script setup>
...
const emit = defineEmits(['resolve', 'reject']);
...
</script>
<script>
export default {
...
emits: ['resolve', 'reject'],
...
}
</script>
The open
function takes 3 arguments and returns a Promise
containing a reference to the Modal itself.
- The Modal Component
- The Modal Configuration
- Props for the Modal Component
These are configurations used to open your Modal
Property | Type | Default | Description |
---|---|---|---|
rejectOnBackdrop | boolean | true | if true invoke reject when the user click out of your component |
An object containing props you'd like to set into your Modal Component.
Example:
InfoModal.vue
<script setup>
const props = defineProps({
msg: String
});
const emits = defineEmits(['resolve', 'reject']);
</script>
<template>
<div>
<p>{{ msg }}</p>
<button @click="emits('resolve')">OK</button>
</div>
</template>
<script setup>
...
const modals = useModals();
modals.open(InfoModal,
{ rejectOnBackdrop: false },
{ msg: 'Click in "OK" if you read this!' }
);
...
</script>
Cover all this scenarios:
- Retrieve data to the calling component when closing the modal
- Have positive and negative responses from Modal and handle it in the most JS way
- The Modal may close without the user directly interacting with its closing process, like changing route or programmatically forcing the modal to close
A confirmation Modal would resolve
if the user confirm it and reject
if deny it.
Your Modal:
<div>
<p>Are you sure of this decision?<p>
<button @click="emit('reject')">No, I'm having second thoughts</button>
<button @click="emit('resolve')">Hell yeah I'm sure</button>
</div>
Component opening the confirmation modal:
<script setup>
import { useModals } from 'vue-modal4real';
import ConfirmationModal from '@/components/ConfirmationModal.vue';
const modals = useModals();
modals.open(ConfirmationModal)
.then(() => console.log('The user knows too much'))
.catch(() => console.log('Everything is under control'));
</script>
This lib doesn't have any css with it, you are free to style your modals the way you like the most.
The only style treatment this lib does is blocking the page scroll when a modal is opened.
The classes you must implement to style the modal backdrop and the modal placement is modalContainer
and modalContent
.
modalContainer
is a container div used for background/backdrop.
modalContent
is the only modalContainer
child and it's were your Modal Component will be rendered.
A simple css to open your modal with a black backdrop with your Modal placed in the center.
Here it fix the modalContainer
with full width and height and apply a black background color with 20% opacity.
.modalContainer {
position: fixed;
width: 100vw;
height: 100vh;
top: 0;
left: 0;
background-color: rgba(0,0,0, .2);
}
Here it places to modalContent
in page center using relative top and left and set a flex display for your component to be rendered.
.modalContainer .modalContent {
position: relative;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
padding: 16px;
}