Custom Directives
Introduction
In addition to the default set of directives shipped in core (like
v-model
or
v-show
), Vue also allows you to register your own custom directives.
We have introduced two forms of code reuse in Vue: components and composables . Components are the main building blocks, while composables are focused on reusing stateful logic. Custom directives, on the other hand, are mainly intended for reusing logic that involves low-level DOM access on plain elements.
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. Here is an example of a directive that focuses an input when the element is inserted into the DOM by Vue:
Assuming you haven't clicked elsewhere on the page, the input above should be auto-focused. This directive is more useful than the
autofocus
attribute because it works not just on page load - it also works when the element is dynamically inserted by Vue.
In
<script setup>
, any camelCase variable that starts with the
v
prefix can be used as a custom directive. In the example above,
vFocus
can be used in the template as
v-focus
.
If not using
<script setup>
, custom directives can be registered using the
directives
option:
It is also common to globally register custom directives at the app level:
TIP
Custom directives should only be used when the desired functionality can only be achieved via direct DOM manipulation. Prefer declarative templating using built-in directives such as
v-bind
when possible because they are more efficient and server-rendering friendly.
Directive Hooks
A directive definition object can provide several hook functions (all optional):
Hook Arguments
Directive hooks are passed these arguments:
-
el
: the element the directive is bound to. This can be used to directly manipulate the DOM. -
binding
: an object containing the following properties.-
value
: The value passed to the directive. For example inv-my-directive="1 + 1"
, the value would be2
. -
oldValue
: The previous value, only available inbeforeUpdate
andupdated
. It is available whether or not the value has changed. -
arg
: The argument passed to the directive, if any. For example inv-my-directive:foo
, the arg would be"foo"
. -
modifiers
: An object containing modifiers, if any. For example inv-my-directive.foo.bar
, the modifiers object would be{ foo: true, bar: true }
. -
instance
: The instance of the component where the directive is used. -
dir
: the directive definition object.
-
-
vnode
: the underlying VNode representing the bound element. -
prevVnode
: the VNode representing the bound element from the previous render. Only available in thebeforeUpdate
andupdated
hooks.
As an example, consider the following directive usage:
The
binding
argument would be an object in the shape of:
Similar to built-in directives, custom directive arguments can be dynamic. For example:
Here the directive argument will be reactively updated based on
arg
property in our component state.
Note
Apart from
el
, you should treat these arguments as read-only and never modify them. If you need to share information across hooks, it is recommended to do so through element's
dataset
.
Function Shorthand
It's common for a custom directive to have the same behavior for
mounted
and
updated
, with no need for the other hooks. In such cases we can define the directive as a function:
Object Literals
If your directive needs multiple values, you can also pass in a JavaScript object literal. Remember, directives can take any valid JavaScript expression.
Usage on Components
When used on components, custom directives will always apply to a component's root node, similar to Fallthrough Attributes .