自定义指令可以通过全局注册或局部注册两种方式创建。选择哪种方式取决于指令的使用范围。
全局注册的指令可以在任何组件中使用:
Vue.directive('focus', {
inserted: function(el) {
el.focus()
}
})
使用:
<template>
<div>
<input v-focus>
</div>
</template>
全局注册通常在入口文件中进行:
import Vue from 'vue'
import App from './App.vue'
Vue.directive('focus', {
inserted(el) {
el.focus()
}
})
new Vue({
render: h => h(App)
}).$mount('#app')
将多个指令放在一个文件中统一注册:
import Vue from 'vue'
const directives = {
focus: {
inserted(el) {
el.focus()
}
},
color: {
bind(el, binding) {
el.style.color = binding.value
}
},
permission: {
inserted(el, binding) {
if (!binding.value) {
el.parentNode && el.parentNode.removeChild(el)
}
}
}
}
Object.keys(directives).forEach(key => {
Vue.directive(key, directives[key])
})
局部注册的指令只能在当前组件中使用:
<template>
<div>
<input v-focus>
</div>
</template>
<script>
export default {
directives: {
focus: {
inserted(el) {
el.focus()
}
}
}
}
</script>
<template>
<div>
<p v-highlight="'yellow'">高亮文本</p>
</div>
</template>
<script>
export default {
directives: {
highlight: {
bind(el, binding) {
el.style.backgroundColor = binding.value
}
}
}
}
</script>
当只需要 bind 和 update 时执行相同逻辑,可以使用函数简写:
Vue.directive('color', function(el, binding) {
el.style.color = binding.value
})
等价于:
Vue.directive('color', {
bind(el, binding) {
el.style.color = binding.value
},
update(el, binding) {
el.style.color = binding.value
}
})
如果指令需要多个值,可以传入对象:
<div v-demo="{ color: 'white', text: 'hello' }"></div>
<script>
Vue.directive('demo', {
bind(el, binding) {
console.log(binding.value.color) // 'white'
console.log(binding.value.text) // 'hello'
}
})
</script>
将指令封装成插件:
const MyDirectives = {
install(Vue) {
Vue.directive('focus', {
inserted(el) {
el.focus()
}
})
Vue.directive('click-outside', {
bind(el, binding, vnode) {
el.clickOutsideEvent = function(event) {
if (!(el === event.target || el.contains(event.target))) {
binding.value(event)
}
}
document.body.addEventListener('click', el.clickOutsideEvent)
},
unbind(el) {
document.body.removeEventListener('click', el.clickOutsideEvent)
}
})
}
}
export default MyDirectives
使用插件:
import Vue from 'vue'
import MyDirectives from './directives'
Vue.use(MyDirectives)
使用全局注册:
使用局部注册:
Vue.directive('my-directive', {}) // 短横线命名
// 使用时
<div v-my-directive></div>
注意:注册时使用短横线命名,使用时加上 v- 前缀。
<!DOCTYPE html>
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script>
</head>
<body>
<div id="app">
<h2>全局指令</h2>
<input v-focus placeholder="自动聚焦">
<h2>局部指令</h2>
<p v-highlight="'#ffeb3b'">高亮文本</p>
</div>
<script>
Vue.directive('focus', {
inserted(el) {
el.focus()
}
})
new Vue({
el: '#app',
directives: {
highlight: {
bind(el, binding) {
el.style.backgroundColor = binding.value
el.style.padding = '10px'
}
}
}
})
</script>
</body>
</html>
掌握指令注册后,接下来学习钩子函数,了解指令的生命周期。