Vue Universal Modal
Vue Universal Modal is a lightweight and simple modal plugin specifically designed for Vue 3 applications, leveraging Vue's built-in `teleport` feature. Currently at version 1.1.4, its release cadence appears to be relatively infrequent, with updates primarily focusing on bug fixes and dependency bumps since its last feature addition in v1.1.0 in April 2021. Key differentiators include its reliance on `teleport` for efficient DOM management, built-in accessibility (A11Y) features, and support for Server-Side Rendering (SSR) by requiring a pre-defined teleport target in the HTML. It provides essential modal functionalities like add/remove, visibility control, transitions, and automatic keyboard/mouse binding for closing, making it a robust solution for managing modals in modern Vue applications.
Common errors
-
[Vue warn]: Failed to resolve component: Modal
cause The `Modal` component either wasn't globally registered, or the `modalComponent` option in `app.use()` was changed to a different name.fixEnsure `app.use(VueUniversalModal, { ... })` is called before mounting your app, and that you are using the correct `modalComponent` name (default is 'Modal') in your template. -
TypeError: app.use is not a function
cause Attempting to use `VueUniversalModal` with Vue 2's `Vue.use()` syntax or an incorrect Vue instance.fixThis plugin is for Vue 3. Ensure you are importing `createApp` from 'vue' and calling `app.use()` on the application instance returned by `createApp()`. -
Modal does not show or close with smooth animations, it just appears/disappears instantly.
cause The modal's visibility is being controlled with `v-if` instead of `v-model`, preventing Vue's transition system from hooking into the component's lifecycle for animations.fixChange the usage from `<Modal v-if="isShow" ...>` to `<Modal v-model="isShow" ...>`. The `v-model` directive correctly manages the presence of the component in the DOM for transitions.
Warnings
- breaking The modal component's visibility control changed from using `v-if` to `v-model`. Using `v-if` will prevent close animations from working correctly, and the `emitClose` slot argument was deprecated.
- breaking This plugin is exclusively designed for Vue 3. It does not support Vue 2 applications, and attempting to use it will result in errors related to Vue 3 specific features like `teleport`.
- gotcha The `teleportTarget` option, which specifies where the modal content is rendered in the DOM, must point to an element that is already present in your `index.html` file. This is particularly important for Server-Side Rendering (SSR) environments.
- gotcha While the plugin handles basic modal functionality, it does not provide custom styling out-of-the-box beyond a minimal `index.css`. Developers are expected to provide their own styles for the modal content and potentially the overlay.
Install
-
npm install vue-universal-modal -
yarn add vue-universal-modal -
pnpm add vue-universal-modal
Imports
- VueUniversalModal
const VueUniversalModal = require('vue-universal-modal');import VueUniversalModal from 'vue-universal-modal';
- CSS Styles
import 'vue-universal-modal/dist/index.css';
- Modal Component
<Modal v-model="isShow">...</Modal>
Quickstart
import { createApp, ref, defineComponent } from 'vue';
import VueUniversalModal from 'vue-universal-modal';
import 'vue-universal-modal/dist/index.css';
// Assuming you have an index.html with <div id="app"></div> and <div id="modals"></div>
const app = createApp({
template: `
<p>
<button @click="showModal">Show modal</button>
</p>
<Modal v-model="isShow" :close="closeModal">
<div class="modal-content">
<p>Hello from Universal Modal!</p>
<button @click="closeModal">Close Modal</button>
</div>
</Modal>
`,
setup() {
const isShow = ref(false);
function showModal() {
isShow.value = true;
}
function closeModal() {
isShow.value = false;
}
return {
isShow,
showModal,
closeModal,
};
},
});
app.use(VueUniversalModal, {
teleportTarget: '#modals',
modalComponent: 'Modal', // Default, explicitly set for clarity
});
app.mount('#app');
// Basic CSS for demonstration (include in your main CSS or style block)
// .modal-content {
// width: 300px;
// padding: 30px;
// box-sizing: border-box;
// background-color: #fff;
// font-size: 20px;
// text-align: center;
// }