This article is more than four years old. The content may be outdated, especially technical examples or references to tooling.
Vue components and custom directives both help you reuse code, but they solve different problems. A component defines a piece of your interface, including its template and behaviour. A directive adds behaviour to an existing element when you need direct access to the DOM.
You probably already use built-in directives such as v-if, v-for and v-model. You can also write your own. Here is how to decide when a custom directive is useful and when a component is the better choice.
The differences between components and directives
Characteristics of a component
A component packages a reusable part of the interface. It can have a template, local state, props and events. For example, this counter component owns both the button's appearance and its behaviour:
Vue.component('button-counter', {
data: () => ({
count: 0
}),
template: '<button @click="count++">You clicked me {{ count }} times.</button>'
});
The data function returns a new object for each component instance. The parentheses around ({ count: 0 }) make the arrow function return that object. Without them, the braces would form a function body with no return value.
Use the component in a Vue template with <button-counter></button-counter>. Vue renders the button and updates its text as the count changes. Place two instances on a page and each keeps its own counter.
Components also have their own lifecycle hooks. See the component guide and lifecycle diagram for more detail.
Characteristics of a directive
A custom directive attaches behaviour to an element through an attribute with the v- prefix. It does not define a component template or create its own component instance. A small example is moving focus to an input:
Vue.directive('focus', {
inserted: el => {
el.focus();
}
});
Apply it to a focusable element in your template:
<input type="text" v-focus>
The inserted hook runs when the element is inserted into its parent. This can also happen later, when an element is added dynamically; it is not a page-load event. The parent does not necessarily have to be attached to the document yet.
Unlike a component, a directive has hooks tied to its bound element. The directive documentation describes these five hooks:
bind: runs once when the directive is first bound to the element.inserted: runs when the element is inserted into its parent node.update: runs after the containing component's virtual node updates, possibly before its children update. The directive's value may be unchanged.componentUpdated: runs after the containing component's virtual node and its children's virtual nodes have updated.unbind: runs once when the directive is unbound. Use it to clean up listeners or other resources the directive created.
Should I use a component or a directive?
Start with what you want to reuse. For a button, form field or other interface element with its own markup and behaviour, a component is usually the right place. Props and events give it a clear interface to the rest of the application.
Choose a directive when the reusable behaviour needs direct DOM access and can be attached to an existing element. Focusing an input is a good example: the directive does not need to own the input's value, label or validation messages.
Before writing a directive, check whether a normal Vue binding already handles the job. A class binding or event handler is often enough. Validation rules and API requests do not automatically belong in a directive simply because they relate to an input.
The two approaches can work together. A form-field component can own the label, input and error message while using a focus directive on its input. The decision is about responsibility, not just whether the solution adds another HTML tag.
Conclusion
Use components to build reusable pieces of your interface. Use custom directives for focused behaviour that needs access to an existing DOM element. Keep each responsible for a clear task so the result stays easy to understand and reuse.
