一、自定义指令
1、自己封装指令
什么是指令?指令本质上就是DOM功能的一种抽象封装。
如果有一些DOM功能经常用,但是Vue没有提供相关指令,建议自己封装。
2、自定义全局指令
使用Vue.directive('指令名', function() {})定义全局指令。
3、自定义局部指令
使用directives: {}定义局部指令,只能在当前组件中使用。
(1)使用function写法
javascript
directives: {
// function写法
'color': function(el, binding, vnode) {
console.log('---el', el) // 指令所对应的DOM节点
console.log('---binding', binding) // 绑定的值/表达式
console.log('---vnode', vnode) // 当前的虚拟DOM
el.style.color = binding.value
}
}
接收3个参数:
el:指令所对应的DOM节点
binding:绑定的值/表达式
vnode:当前的虚拟DOM
(2)使用对象写法
javascript
directives: {
// function写法
'color': function(el, binding, vnode) {
console.log('---el', el) // 指令所对应的DOM节点
console.log('---binding', binding) // 绑定的值/表达式
console.log('---vnode', vnode) // 当前的虚拟DOM
el.style.color = binding.value
},
// 对象写法
'color2': {
bind(el, binding) { // 绑定cc变量的时候
el.style.color = binding.value
},
update(el, binding) { // 修改cc变量的时候
el.style.color = binding.value
}
}
}
还有其它的钩子。
注:function写法,等价于bind + update这两个。
二、例子代码
自己封装一个指令v-form,类似于v-model指令实现双向绑定。
必须要用虚拟DOM的上下文实现。
html
<html>
<head>
<title>自定义指令</title>
<style>
</style>
</head>
<body>
<div id="app">
<h1 v-color='"red"'>测试</h1>
<h1 v-color='"blue"'>测试</h1>
<h1 v-color2="cc">测试</h1>
<input type="text" v-form.lazy="name" />
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script>
Vue.directive ('form', {
bind(el, binding, vnode) {
console.log('---el', el)
console.log('---binding', binding)
console.log('---vnode', vnode)
// 解构赋值
const { lazy } = binding.modifiers
// v-bind:value
// 指令在绑值的时候,改上下文中的值
el.value = vnode.context[binding.expression]
// v-on:input
// 实现双向绑定
el.addEventListener(lazy?'blur':'input', function(ev){
console.log('---事件', ev.target.value)
vnode.context[binding.expression] = ev.target.value
})
},
update(el, binding, vnode) {
// 实现双向绑定
el.value = vnode.context[binding.expression]
}
})
const app = new Vue({
data() {
return {
cc: "green",
name: '张三'
}
},
directives: {
// function写法
'color': function(el, binding, vnode) {
//console.log('---el', el) // 指令所对应的DOM节点
//console.log('---binding', binding) // 绑定的值/表达式
//console.log('---vnode', vnode) // 当前的虚拟DOM
el.style.color = binding.value
},
// 对象写法
'color2': {
bind(el, binding) { // 绑定cc变量的时候
el.style.color = binding.value
},
update(el, binding) { // 修改cc变量的时候
el.style.color = binding.value
}
}
}
})
app.$mount('#app')
</script>
</body>
</html>