自定义指令 — Vue.js
1.自定义指令
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
</style>
<script src="https://cdn.staticfile.org/vue/2.4.2/vue.min.js"></script>
</head>
<body>
<div id="app">
<input v-focus>
</div>
<script>
// 注册一个全局自定义指令 `v-focus`
Vue.directive('focus', {
// 当被绑定的元素插入到 DOM 中时……
inserted: function (el) {
// 聚焦元素
el.focus()
}
})
new Vue({
el: '#app'
})
</script>
</body>
</html>
1.1 钩子函数
一个指令定义对象可以提供如下几个钩子函数 (均为可选):
bind
:只调用一次,指令第一次绑定到元素时调用。inserted
:被绑定元素插入父节点时调用。update
:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。componentUpdated
:指令所在组件的 VNode 及其子 VNode 全部更新后调用。unbind
:只调用一次,指令与元素解绑时调用。
指令钩子函数会被传入以下参数:
el
:指令所绑定的元素,可以用来直接操作 DOM 。binding
name
:指令名,不包括v-
前缀。value
oldValue
expression
arg
:传给指令的参数。例如v-my-directive:foo
中,参数为foo
。modifiers
:例如:v-my-directive.foo.bar
中,修饰符对象为{ foo: true, bar: true }
。
vnode
oldVnode
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
</style>
<script src="https://cdn.staticfile.org/vue/2.4.2/vue.min.js"></script>
</head>
<body>
<div id="app" v-demo:foo.a.b="message">
</div>
<script>
Vue.directive('demo', {
bind: function (el, binding) {
var s = JSON.stringify
el.innerHTML = `name: ${s(binding.name)} <br>
value: ${s(binding.value)} <br>
expression: ${s(binding.expression)} <br>
arg: ${s(binding.arg)} <br>
modifiers: ${s(binding.modifiers)} <br>`
}
})
new Vue({
el: '#app',
data: {
message: 'hello!'
}
})
</script>
</body>
</html>
1.1.1 动态指令参数
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
#app {
height: 700px;
}
</style>
<script src="https://cdn.staticfile.org/vue/2.4.2/vue.min.js"></script>
</head>
<body>
<div id="app">
<p>Scroll down the page</p>
<p v-pin="200">Stick me 200px from the top of the page</p>
</div>
<script>
Vue.directive('pin', {
bind: function (el, binding, vnode) {
el.style.position = 'fixed'
el.style.top = binding.value + 'px'
}
})
new Vue({
el: '#app',
data: {
}
})
</script>
</body>
</html>
指令的参数可以是动态的。例如v-mydirective:[argument]="value"
。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
#app {
height: 700px;
}
</style>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<h3>Scroll down inside this section ↓</h3>
<p v-pin:[direction]="200">I am pinned onto the page at 200px to the left.</p>
</div>
<script>
Vue.directive('pin', {
bind: function (el, binding, vnode) {
el.style.position = 'fixed'
var s = (binding.arg == 'left' ? 'left' : 'top')
el.style[s] = binding.value + 'px'
}
})
new Vue({
el: '#app',
data: {
direction: 'left'
}
})
</script>
</body>
</html>
注意:使用动态指令参数需要考虑 Vue.js 的版本。
1.2 对象字面量
如果指令需要多个值,可以传入一个 JavaScript 对象字面量。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
</style>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app" v-demo="{ color: 'white', text: 'hello!' }">
</div>
<script>
Vue.directive('demo', function (el, binding) {
console.log(binding.value.color) // => "white"
console.log(binding.value.text) // => "hello!"
})
new Vue({
el: '#app'
})
</script>
</body>
</html>
注意:Vue.directive('demo', function (el, binding) {})
第二个参数是函数简写(bind
和update
)。
参考: