Vue.js Custom Directives
In addition to the core directives (v-model and v-show) that come with default settings, Vue also allows for the registration of custom directives.
Below, we register a global directive v-focus, which has the functionality to give focus to an element when the page loads:
Example
<div id="app">
<p>When the page loads, the input element automatically gets focus:</p>
<input v-focus>
</div>
<script>
// Register a global custom directive called v-focus
Vue.directive('focus', {
// When the bound element is inserted into the DOM...
inserted: function (el) {
// Focus the element
el.focus()
}
})
// Create the root instance
new Vue({
el: '#app'
})
</script>
We can also register local directives using the directives option within an instance, which makes the directive available only within that instance:
Example
<div id="app">
<p>When the page loads, the input element automatically gets focus:</p>
<input v-focus>
</div>
<script>
// Create the root instance
new Vue({
el: '#app',
directives: {
// Register a local custom directive called v-focus
focus: {
// Directive definition
inserted: function (el) {
// Focus the element
el.focus()
}
}
}
})
</script>
Hooks
Hook Functions
The directive definition function provides several hook functions (optional):
bind
: Called only once, when the directive is first bound to the element. This hook can be used to define an initialization action that executes once.inserted
: Called when the bound element is inserted into its parent node (this only guarantees parent node presence, not necessarily in the document).update
: Called after the containing component’s VNode has updated, regardless of whether the directive’s value has changed. By comparing the updated value before and after, unnecessary updates can be ignored (see detailed hook function parameters below).componentUpdated
: Called after the containing component’s VNode and the VNodes of its children have updated.unbind
: Called only once, when the directive is unbound from the element.
Hook Function Parameters
The hook functions have the following parameters:
el: The element the directive is bound to, which can be used to manipulate the DOM directly.
binding: An object containing the following properties:
name: The name of the directive, without the
v-
prefix.value: The value bound to the directive. For example,
v-my-directive="1 + 1"
, the value would be2
.oldValue: The previous value bound to the directive, available only in the
update
andcomponentUpdated
hooks. It is available regardless of whether the value has changed.expression: The expression of the binding as a string. For example,
v-my-directive="1 + 1"
, the expression would be"1 + 1"
.arg: The argument passed to the directive. For example,
v-my-directive:foo
, the arg would be"foo"
.modifiers: An object containing modifiers. For example,
v-my-directive.foo.bar
, the modifiers object would be{ foo: true, bar: true }
.vnode: The virtual node produced by Vue’s compiler.
oldVnode: The previous virtual node, only available in the
update
andcomponentUpdated
hooks.
The following example demonstrates the use of these parameters:
Example
<div id="app" v-tutorialpro:hello.a.b="message">
</div>
<script>
Vue.directive('tutorialpro', {
bind: function (el, binding, vnode) {
var s = JSON.stringify
el.innerHTML =
'name: ' + s(binding.name) + '<br>' +
'value: ' + s(binding.value) + '<br>' +
'expression: ' + s(binding.expression) + '<br>' +
'argument: ' + s(binding.arg) + '<br>' +
'modifiers: ' + s(binding.modifiers) + '<br>' +
'vnode keys: ' + Object.keys(vnode).join(', ')
}
})
new Vue({
el: '#app',
data: {
message: 'hello!'
}
})
</script>
<script>
Vue.directive('focus', {
inserted: function (el) {
el.focus()
}
})
Vue.directive('demo', function (el, binding, vnode) {
el.innerHTML =
'modifiers: ' + JSON.stringify(binding.modifiers) + '<br>' +
'vnode keys: ' + Object.keys(vnode).join(', ')
}
})
new Vue({
el: '#app',
data: {
message: 'tutorialpro.org!'
}
})
</script>
Sometimes we don't need other hook functions, we can simplify the function in the following format:
Vue.directive('tutorialpro', function (el, binding) {
// Set the background color of the directive
el.style.backgroundColor = binding.value.color
})
The directive function can accept all valid JavaScript expressions. The following example passes a JavaScript object:
Example
<div id="app">
<div v-tutorialpro="{ color: 'green', text: 'tutorialpro.org!' }"></div>
</div>
<script>
Vue.directive('tutorialpro', function (el, binding) {
// Simplified way to set text and background color
el.innerHTML = binding.value.text
el.style.backgroundColor = binding.value.color
})
new Vue({
el: '#app'
})
</script>