除了核心功能默认内置的指令外,vue也允许用户注册自定义指令。虽然在vue2.0中,代码复用和抽象的主要形式是组件,但是有些情况下,我们仍需要对普通DOM元素进行底层操作,这个时候就需要用到自定义指令,例如,我们希望将元素的背景色变为红色,就可以通过指令实现。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>vue</title> <style></style> <script src="vue.js"></script> </head> <body> <div id="box"> <p v-red>aaaaa</p> <p v-red>12345</p> <p v-red>自定义</p> </div> <script> Vue.directive(\'red\',function(){ this.el.style.background=\'red\'; }); var vm=new Vue({ el:\'#box\', data:{ msg:\'welcome\' } }); </script> </body> </html>
上面简单的实例中,主要是展示了自定义组件的用法:
其中"red"为我们自定义的指令,在使用的时候,需要加上"v-"的前缀,后面接的方法是该指令需要实现的功能;"el"是指令所绑定的元素,可以用来直接操作DOM。
自定义指令传参
在上面的自定义指令中,我们实现了将元素背景色变为红色,那么如果我们需要将背景色改为蓝色,只是颜色改变了,其他的都是一样的,若这样再重新定义一个指令,就完全没必要了,因此我们可以考虑传参的方法了。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>vue</title> <style></style> <script src="vue.js"></script> </head> <body> <div id="box"> <p v-red=\'r\'>aaaaa</p> <p v-red=\'g\'>12345</p> <p v-red=\'p\'>自定义</p> </div> <script> Vue.directive(\'red\',function(color){ this.el.style.background=color; }); var vm=new Vue({ el:\'#box\', data:{ r:\'red\', g:\'gray\', p:\'pink\' } }); </script> </body> </html>
但是上面的这种的方式的要求是我们必须现在vue实例中声明这些颜色参数,并不能满足我们想要随意更换颜色的要求,因此,需要继续优化。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>vue</title> <style></style> <script src="vue.js"></script> </head> <body> <div id="box"> <p v-red="\'red\'">aaaaa</p> <p v-red="\'gray\'">12345</p> <p v-red="\'pink\'">自定义</p> </div> <script> Vue.directive(\'red\',function(color){ this.el.style.background=color; }); var vm=new Vue({ el:\'#box\', }); </script> </body> </html>
自定义指令获取事件属性
和其他JavaScript事件一样,自定义指令事件也能获取事件属性,例如键盘事件,鼠标事件等,下面通过获取鼠标位置实现自定义拖拽指令。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>vue</title> <style> </style> <script src="vue.js"></script> </head> <body> <div id="box"> <div v-drag :style="{width:\'100px\', height:\'100px\', background:\'blue\', position:\'absolute\', right:0, top:0}"></div> <div v-drag :style="{width:\'100px\', height:\'100px\', background:\'red\', position:\'absolute\', left:0, top:0}"></div> </div> <script> Vue.directive(\'drag\',function(){ var oDiv=this.el; oDiv.onmousedown=function(ev){ var disX=ev.clientX-oDiv.offsetLeft; var disY=ev.clientY-oDiv.offsetTop; document.onmousemove=function(ev){ var l=ev.clientX-disX; var t=ev.clientY-disY; oDiv.style.left=l+\'px\'; oDiv.style.top=t+\'px\'; }; document.onmouseup=function(){ document.onmousemove=null; document.onmouseup=null; }; }; }); var vm=new Vue({ el:\'#box\', data:{ msg:\'welcome\' } }); </script> </body> </html>
拖拽前:
拖拽后:
自定义元素指令
所谓自定义元素指令,就是指该指令能够像其他的元素如div,span等一样直接使用,既然是元素指令,自然就和其他的自定义指令不一样了,下面通过一个简单的例子来展示自定义元素指令的用法,依旧是改变元素的背景色,具体实现如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>vue</title> <style> </style> <script src="vue.js"></script> </head> <body> <div id="box"> <zns-red>自定义元素指令</zns-red> </div> <script> Vue.elementDirective(\'zns-red\',{ bind:function(){ this.el.style.background=\'red\'; } }); var vm=new Vue({ el:\'#box\', data:{ a:\'blue\' } }); </script> </body> </html>
自定义指令和自定义元素指令相比,主要存在三个不同之处:
- 自定义指令使用elementDirective
- 自定义指令的功能函数直接写在后面的方法中,自定义元素指令的功能函数必须写在钩子函数中(bind、inserted等)
- 自定义指令在使用时,需要用v-开头,添加到需要的元素中;自定义元素指令则是直接像其他元素一样使用即可。