directive definition
A directive refers to template attributes beginning with the v- prefix, or their equivalent shorthands. Built-in directives include v-if, v-for, v-bind, v-on, and v-slot. Vue also supports creating custom directives, though they are typically only used as an escape hatch for manipulating DOM nodes directly.
Custom directive definition structure
A custom directive is defined as an object containing lifecycle hooks similar to those of a component. The hooks receive the element the directive is bound to.
Custom directive in script setup with v prefix naming
In <script setup>, any camelCase variable that starts with the v prefix can be used as a custom directive. For example, vHighlight can be used in the template as v-highlight.
Custom directive local registration in Composition API
In Composition API without <script setup>, custom directives can be registered using the directives option on the component export.
Custom directive local registration in Options API
In Options API, custom directives must be registered using the directives option so they can be used in templates.
Global custom directive registration
To globally register a custom directive at the app level, use app.directive('directiveName', directiveDefinition). This makes the directive usable in all components.
When to use custom directives
Custom directives should only be used when the desired functionality can only be achieved via direct DOM manipulation. Declarative templating with built-in directives such as v-bind is recommended when possible because they are more efficient and server-rendering friendly.
Custom directive lifecycle hooks
A directive definition object can provide these optional hook functions: created (before attributes/event listeners are applied), beforeMount (right before insertion into DOM), mounted (after parent component and children are mounted), beforeUpdate (before parent update), updated (after parent and children update), beforeUnmount (before parent unmount), and unmounted (when parent is unmounted).
Directive hook arguments: el
The el argument in directive hooks is the element the directive is bound to. This can be used to directly manipulate the DOM.
Directive hook arguments: binding object
The binding argument is an object containing: value (the value passed to the directive), oldValue (previous value, only in beforeUpdate and updated), arg (directive argument if any), modifiers (object of modifiers if any), instance (component instance where directive is used), and dir (the directive definition object).
Directive hook arguments: vnode and prevVnode
The vnode argument is the underlying VNode representing the bound element. The prevVnode argument is the VNode from the previous render, only available in beforeUpdate and updated hooks.
Directive hook arguments are read-only
Apart from el, directive hook arguments should be treated as read-only and never modified. To share information across hooks, use the element's dataset property.
Dynamic directive arguments
Custom directive arguments can be dynamic using bracket notation. For example, v-example:[arg]="value" will reactively update the directive argument based on the arg property in component state.
Custom directive function shorthand
When a custom directive needs the same behavior for mounted and updated with no other hooks needed, the directive can be defined as a function instead of an object. This function will be called for both mounted and updated.
Custom directive with object literal values
A custom directive can accept JavaScript object literals as values. For example, v-demo="{ color: 'white', text: 'hello!' }" passes an object to the directive, accessible via binding.value.
Custom directives on components not recommended
Using custom directives on components is not recommended because unexpected behaviour may occur when a component has multiple root nodes.
Custom directive application to component root node
When a custom directive is used on a component, it will always apply to the component's root node, similar to Fallthrough Attributes.
Custom directive behavior on multi-root components
When a custom directive is applied to a multi-root component, the directive will be ignored and a warning will be thrown. Directives cannot be passed to a different element with v-bind="$attrs".
v-focus custom directive example
A common use case for custom directives is v-focus, which brings an element into focus. Unlike the autofocus attribute, a custom v-focus directive works not just on page load but also when the element is dynamically inserted by Vue.
v-highlight custom directive example
Example of a custom directive that adds a class to an element when it is inserted into the DOM. In <script setup>: const vHighlight = { mounted: (el) => { el.classList.add('is-highlight') } } can be used as <p v-highlight>text</p>