In addition to the default set of directives shipped in core, Vue.js also allows you to register custom directives. Custom directives provide a mechanism for mapping data changes to arbitrary DOM behavior.
You can register a global custom directive with the Vue.directive(id, definition)
method, passing in a directive id followed by a definition object. You can also register a local custom directive by including it in a component’s directives
option.
Hook Functions
bind
with the initial value, then again whenever the binding value changes. The new value and the previous value are provided as the argument.Vue.directive('my-directive', {
bind: function () {
// do preparation work
// e.g. add event listeners or expensive stuff
// that needs to be run only once
},
update: function (newValue, oldValue) {
// do something based on the updated value
// this will also be called for the initial value
},
unbind: function () {
// do clean up work
// e.g. remove event listeners added in bind()
}
})
Once registered, you can use it in Vue.js templates like this (remember to add the v-
prefix):
<div v-my-directive="someValue"></div>
When you only need the update
function, you can pass in a single function instead of the definition object:
Vue.directive('my-directive', function (value) {
// this function will be used as update()
})
Directive Instance Properties
All the hook functions will be copied into the actual directive object, which you can access inside these functions as their this
context. The directive object exposes some useful properties:
You should treat all these properties as read-only and never modify them. You can attach custom properties to the directive object too, but be careful not to accidentally overwrite existing internal ones.
An example of a custom directive using some of these properties:
HTML
<div id="demo" v-demo:hello.a.b="msg"></div>
JavaScript
Vue.directive('demo', {
bind: function () {
console.log('demo bound!')
},
update: function (value) {
this.el.innerHTML =
'name - ' + this.name + '<br>' +
'expression - ' + this.expression + '<br>' +
'argument - ' + this.arg + '<br>' +
'modifiers - ' + JSON.stringify(this.modifiers) + '<br>' +
'value - ' + value
}
})
var demo = new Vue({
el: '#demo',
data: {
msg: 'hello!'
}
})
Result
name - demo
expression - msg
argument - hello
modifiers - {"b":true,"a":true}
value - hello!
Object Literal
If your directive needs multiple values, you can also pass in a JavaScript object literal. Remember, directives can take any valid JavaScript expression:
HTML
<div v-demo="{ color: 'white', text: 'hello!' }"></div>
JavaScript
Vue.directive('demo', function (value) {
console.log(value.color) // "white"
console.log(value.text) // "hello!"
})
Literal Modifier
When a directive is used with the literal modifier, its attribute value will be interpreted as a plain string and passed directly into the update
method. The update
method will also be called only once, because a plain string cannot be reactive.
HTML
<div v-demo.literal="foo bar baz">
JavaScript
Vue.directive('demo', function (value) {
console.log(value) // "foo bar baz"
})