Vue Helper Directives (vdirs)
vdirs is a specialized collection of utility directives designed exclusively for Vue 3 applications, currently available at version 0.1.8. It offers practical functionalities such as `v-zindexable` for automated z-index management of elements, `v-clickoutside` to detect clicks occurring outside of a bound element, and `v-mousemoveoutside` for similar mouse movement detection. While an explicit release cadence isn't defined, typical for smaller utility libraries, updates are likely driven by bug fixes or feature additions. Its primary advantage lies in providing ready-to-use, commonly required UI interaction patterns, which helps to minimize boilerplate code and ensure consistent behavior across a Vue project. The library includes comprehensive TypeScript type definitions, significantly improving development experience in typed environments.
Common errors
-
[Vue warn]: Failed to resolve directive: zindexable
cause The `zindexable` directive was used in a template but not registered in the component's `directives` option or globally.fixEnsure `zindexable` is imported and added to the `directives` object within your Vue component options (e.g., `directives: { zindexable }`) or registered globally during app initialization. -
npm ERR! code ERESOLVE npm ERR! ERESOLVE could not resolve npm ERR! peer vue@"^3.0.11" from vdirs@0.1.8
cause Your project's installed version of Vue does not satisfy the peer dependency requirement of `vdirs`.fixUpdate your Vue 3 installation to a version compatible with `^3.0.11` (e.g., `npm install vue@^3.0.11`) or adjust the `vdirs` version if a compatible one exists for your Vue version. -
TypeError: Cannot read properties of undefined (reading 'handler')
cause This error can occur if a directive like `v-clickoutside` expects a function handler but receives an undefined or null value, often due to a typo or incorrect data binding.fixVerify that the value passed to the directive (e.g., `v-clickoutside="myFunction"`) is a valid function or expression that evaluates to a function, and that any reactive data it depends on is correctly defined and accessible.
Warnings
- breaking The package is currently in a 0.1.x version range, which implies that API stability is not guaranteed. Any minor or patch release could potentially introduce breaking changes without a major version increment.
- gotcha The library explicitly lists `Vue: ^3.0.11` as a peer dependency. Using older Vue 3 versions or significantly newer beta/RC versions might lead to unexpected behavior or runtime errors.
- gotcha Like all Vue custom directives, `vdirs` directives must be explicitly registered globally or locally within components using the `directives` option. Forgetting to register them will prevent them from working.
Install
-
npm install vdirs -
yarn add vdirs -
pnpm add vdirs
Imports
- zindexable
import zindexable from 'vdirs'
import { zindexable } from 'vdirs' - clickoutside
const { clickoutside } = require('vdirs')import { clickoutside } from 'vdirs' - mousemoveoutside
import * as vdirs from 'vdirs'
import { mousemoveoutside } from 'vdirs'
Quickstart
<template>
<div class="app-container">
<button @click="showModal = true">Open Z-indexable Modal</button>
<div
v-if="showModal"
v-zindexable="{ enabled: showModal, zIndex: 1000 }"
v-clickoutside="handleCloseModal"
class="modal"
>
<h3>Z-indexable Modal</h3>
<p>This modal gets a dynamic z-index and closes on outside click.</p>
<button @click="showModal = false">Close</button>
</div>
<p class="explanation">Click the button to open the modal. The modal will have its z-index managed and will close if you click outside of it.</p>
</div>
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue';
import { zindexable, clickoutside } from 'vdirs';
export default defineComponent({
name: 'App',
directives: {
zindexable,
clickoutside,
},
setup() {
const showModal = ref(false);
const handleCloseModal = (event: MouseEvent) => {
console.log('Clicked outside modal:', event);
showModal.value = false;
};
return {
showModal,
handleCloseModal,
};
},
});
</script>
<style>
.app-container {
font-family: Arial, sans-serif;
padding: 20px;
display: flex;
flex-direction: column;
align-items: center;
gap: 20px;
}
.modal {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: white;
border: 1px solid #ccc;
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
padding: 25px;
border-radius: 8px;
min-width: 300px;
max-width: 90vw;
text-align: center;
z-index: 10; /* Initial z-index, will be overridden by v-zindexable */
}
.modal h3 {
margin-top: 0;
color: #333;
}
.modal p {
color: #555;
margin-bottom: 20px;
}
.modal button {
padding: 8px 15px;
background-color: #007bff;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 16px;
}
.modal button:hover {
background-color: #0056b3;
}
.explanation {
margin-top: 30px;
font-style: italic;
color: #666;
}
</style>