Vue Directive Pattern
Create custom Vue directives for low-level DOM manipulation and reusable DOM behavior
When to Use
- You need reusable DOM manipulation logic (auto-focus, click-outside, intersection observer, tooltips)
- The behavior is purely DOM-level and does not involve component state or rendering
- Integrating third-party libraries that need direct DOM access
Instructions
- Define a directive as an object with lifecycle hooks (
mounted, updated, unmounted).
- Register globally via
app.directive('name', directiveObj) or locally in <script setup> with vName convention.
- Access the element as the first argument and binding value as the second.
- Use directives only for DOM manipulation — for logic, prefer composables.
// v-focus directive — auto-focuses an input on mount
const vFocus = {
mounted(el: HTMLElement) {
el.focus();
},
};
// Usage in template: <input v-focus />
- Clean up event listeners and observers in the
unmounted hook to prevent memory leaks.
- Use
binding.value to pass dynamic data: <div v-tooltip="'Hello'">.
Details
Custom directives give you low-level access to DOM elements. They run at specific lifecycle points (created, beforeMount, mounted, beforeUpdate, updated, beforeUnmount, unmounted) and receive the element and binding information. Vue's built-in directives (v-if, v-show, v-model) are implemented the same way.
Trade-offs:
- Directives are harder to test than composables — they require a real or mocked DOM
- No reactive return value — directives modify the DOM imperatively, not declaratively
- Overusing directives leads to "jQuery-style" code that bypasses Vue's reactivity
When NOT to use:
- When a composable can achieve the same result — composables are easier to test and compose
- For complex component behavior — use a component, not a directive
- When the DOM manipulation is a one-time setup — inline it in
onMounted
Source
https://patterns.dev/vue/directive-pattern
Process
- Read the instructions and examples in this document.
- Apply the patterns to your implementation, adapting to your specific context.
- Verify your implementation against the details and edge cases listed above.
Harness Integration
- Type: knowledge — this skill is a reference document, not a procedural workflow.
- No tools or state — consumed as context by other skills and agents.
Success Criteria
- The patterns described in this document are applied correctly in the implementation.
- Edge cases and anti-patterns listed in this document are avoided.
1---2name: vue-directive-pattern3description: Vue Directive Pattern4---5# Vue Directive Pattern67> Create custom Vue directives for low-level DOM manipulation and reusable DOM behavior89## When to Use1011- You need reusable DOM manipulation logic (auto-focus, click-outside, intersection observer, tooltips)12- The behavior is purely DOM-level and does not involve component state or rendering13- Integrating third-party libraries that need direct DOM access1415## Instructions16171. Define a directive as an object with lifecycle hooks (`mounted`, `updated`, `unmounted`).182. Register globally via `app.directive('name', directiveObj)` or locally in `<script setup>` with `vName` convention.193. Access the element as the first argument and binding value as the second.204. Use directives only for DOM manipulation — for logic, prefer composables.2122```typescript23// v-focus directive — auto-focuses an input on mount24const vFocus = {25 mounted(el: HTMLElement) {26 el.focus();27 },28};2930// Usage in template: <input v-focus />31```32335. Clean up event listeners and observers in the `unmounted` hook to prevent memory leaks.346. Use `binding.value` to pass dynamic data: `<div v-tooltip="'Hello'">`.3536## Details3738Custom directives give you low-level access to DOM elements. They run at specific lifecycle points (created, beforeMount, mounted, beforeUpdate, updated, beforeUnmount, unmounted) and receive the element and binding information. Vue's built-in directives (`v-if`, `v-show`, `v-model`) are implemented the same way.3940**Trade-offs:**4142- Directives are harder to test than composables — they require a real or mocked DOM43- No reactive return value — directives modify the DOM imperatively, not declaratively44- Overusing directives leads to "jQuery-style" code that bypasses Vue's reactivity4546**When NOT to use:**4748- When a composable can achieve the same result — composables are easier to test and compose49- For complex component behavior — use a component, not a directive50- When the DOM manipulation is a one-time setup — inline it in `onMounted`5152## Source5354https://patterns.dev/vue/directive-pattern5556## Process57581. Read the instructions and examples in this document.592. Apply the patterns to your implementation, adapting to your specific context.603. Verify your implementation against the details and edge cases listed above.6162## Harness Integration6364- **Type:** knowledge — this skill is a reference document, not a procedural workflow.65- **No tools or state** — consumed as context by other skills and agents.6667## Success Criteria6869- The patterns described in this document are applied correctly in the implementation.70- Edge cases and anti-patterns listed in this document are avoided.