【VUE】使用和创建指令

694 阅读4分钟

指令:写在HTML元素上,以v-开头的短命令,后面跟指令名(v-部分并不是指令名的一部分,只是用来告诉Vue这个不是可以忽略的普通HTML属性,而是需要处理的指令),例:v-bind,v-on这些内置指令,此外还可以自定义指令。

1.配置指令的五个钩子(Hooks)

  • bind(el,binding,vnode)

    一旦指令完成绑定,可以访问到那个元素,就会触发

    • el:指令所绑定的元素
    • binding(只读):使用指令时的配置

    (传入什么参数,什么修饰符)

    • vnode(只读):虚拟DOM中的节点

只读:不要改动指令下该性质的参数,本该由vue来控制,在运行过程中,不应被改动。

  • inserted(el,binding,vnode)

    成功插入到父节点,它会被插入到DOM后

    一旦该元素改变了部分DOM之后,立刻触发,可以在初次调用前访问它,不需要等他被插入到DOM后再调整样式或者做出修改。不管怎么都可以在被插入时,将改动表达出来。

  • update(el,binding,vnode,oldVnode)

    一旦组件更新完,不包括子组件,此时子组件尚未更新。经过更新虚拟DOM中有了新旧两个节点。两个节点以及binding是只读。

  • componentUpdated(el,binding,vnode,oldVnode)

    一旦组件更新完,包括子组件全部更新完之后调用。

  • unbind(el,binding,vnode)

    一旦指令被移除

    内置指令例:
    //双引号里面还要加上单引号,因为双引号内只能写JavaScript表达式
    <p v-text="'some Text'"></p>
    //some Text
    
    //写入HTML代码,用字符串来写,用这个指令时要注意检查输入内容的安全性。确保不会被跨站脚本攻击
    <p v-html="'<strong>some strong Text</strong>'"></p>
    
    
    自定义指令(类似组件)

    指令的运行离不开钩子

    三要素:参数,修饰符和值

    1.全局注册
    //TEST01设置固定背景色
    //main.js
    Vue.directive('hightlight',{
    	bind(el,binding,vnode){
    		el.style.backgroundColor = 'green';
    	}
    })
    
    //App.vue
    v-highlight
    
    

    第一个参数是选择器,也就是指令名(不加v-的部分)创建全局指令,第二个参数用来配置指令的对象,就像方法一样,我们在这添一个bind钩子,就像组件内的生命周期方法,el是原生的html元素,可以操控他的style属性

    //TEST02设置背景色
    //main.js
    Vue.directive('hightlight',{
    	bind(el,binding,vnode){
    		el.style.backgroundColor = binding.value;
    	}
    })
    
    //App.vue
    v-highlight="'red'"
    
    

    binding是指令与HTML元素绑定时传入的信息

    //TEST03让用户决定设置背景颜色还是设置文本颜色(默认行为)
    //main.js
    Vue.directive('hightlight',{
    	bind(el,binding,vnode){
    		if (binding.arg == 'background'){
    		el.style.backgroundColor = binding.value;
    		}else{
    				el.style.color = binding.value;
    		}
    	}
    })
    
    //App.vue
    v-highlight:background=“'red'

    指令: 用value获取引号间的内容,用arg获取冒号后的信息

    切换要刷新显示,热加载在这里不好用

    修饰符:作用延迟显示

    //TEST04延迟显示修饰符
    //main.js
    Vue.directive('hightlight',{
    	bind(el,binding,vnode){
    	//默认设置为0,也就是没有延迟
    		var delay = 0; 
    		if (binding.modifiers['delayed']){
    		delay = 3000;
    		}
    		setTimeout(()=>{
    			if (binding.arg == 'background'){
    				el.style.backgroundColor = binding.value;
    			}else{
    				el.style.color = binding.value;
    			}
    		},delay);
    
    	}
    })
    
    //App.vue
    v-highlight:background.delayed=“'red'

    modifiers是一个对象,

    v-highlight:background.delayed可以通过点.连接多个修饰符来拥有多个修饰符

    2.本地注册指令

    在任何组件中,都可以使用directives属性添加指令

    (类似components注册局部组件)

    //TEST04本地注册
    //App.vue
    <script>
    export default{
    	components:{
    	
    	}
    	directives:{
    		'local-highlight':{
    			bind(el,binding,vnode){
    					var delay = 0; 
    		if (binding.modifiers['delayed']){
    		delay = 3000;
    		}
    		setTimeout(()=>{
    			if (binding.arg == 'background'){
    				el.style.backgroundColor = binding.value;
    			}else{
    				el.style.color = binding.value;
    			}
    		},delay);
    			}
    		}
    	}
    }
    
    </script>
    //v-local-highlight
    
    

    2.同时使用多个修饰符

    blink设置可使其在两种状态之间切换,指令传入的值可以是字符串也可以是对象,可以用访问对象的方法来访问他

    //TEST04使用多个修饰符
    //App.vue
    v-highlight:background.delayed.blink=“'red'”
    
    //App.vue
    <script>
    export default{
    	components:{
    	
    	}
    	directives:{
    		'local-highlight':{
    			bind(el,binding,vnode){
    					var delay = 0; 
    		if (binding.modifiers['delayed']){
    			delay = 3000;
    		}
    			if (binding.modifiers['blink']){
    				let mainColor = binding.value;
    				let secondColor = 'blue';
    				let currentColor = mainColor;
    				setTimeout(()=>{
    					setInterval(()=>{
    						currentColor == secondColor ?currentColor ==  mainColor:currentColor == secondColor;
    					if (binding.arg == 'background'){
    				el.style.backgroundColor = currentColor;
    			  	}else{
    				el.style.backgroundColor =currentColor ;
    				}
    					},1000)
    
    		},delay);
    		}else{
    				setTimeout(()=>{
    			if (binding.arg == 'background'){
    				el.style.backgroundColor = binding.value;
    			}else{
    				el.style.color = binding.value;
    			}
    		},delay);
    		}
    
    			}
    		}
    	}
    }
    
    </script>
    
    //TEST05控制状态切换
    //App.vue
    v-highlight:background.delayed.blink=“{maincolor:'red',secondColor:'green',delay:500}”
    
    //App.vue
    <script>
    export default{
    	components:{
    	
    	}
    	directives:{
    		'local-highlight':{
    			bind(el,binding,vnode){
    					var delay = 0; 
    		if (binding.modifiers['delayed']){
    			delay = 3000;
    		}
    			if (binding.modifiers['blink']){
    				let mainColor = binding.value.mainColor;
    				let secondColor = binding.value.secondColor;
    				let currentColor = mainColor;
    				setTimeout(()=>{
    					setInterval(()=>{
    						currentColor == secondColor ?currentColor ==  mainColor:currentColor == secondColor;
    					if (binding.arg == 'background'){
    				el.style.backgroundColor = currentColor;
    			  	}else{
    				el.style.backgroundColor =currentColor ;
    				}
    					},binding.value.delay)
    
    		},delay);
    		}else{
    				setTimeout(()=>{
    			if (binding.arg == 'background'){
    				el.style.backgroundColor = binding.value.mainColor;
    			}else{
    				el.style.color = binding.value.mainColor;
    			}
    		},delay);
    		}
    
    			}
    		}
    	}
    }
    
    </script>
    

    3.实现与v-on相似的指令

    //App.vue
    <script>
    export default{
    	directives:{
    		customOn:{
    			bind(el,binding){
    				//el.onclick = function (){
    				//	binding.value();
    				//}
    				const type =binding.arg;
                    const fn =binding.value;
    				el.addEventListener(type,fn);
    				
    			}
    		}
    	},
    	methods:{
    		clicked(){
    		alert('I was clicked!')
    		},
            mouseEnter(){
                console.log('Mouse entered!')
            },
            mouseLeave(){
                console.log('mouse left!')
            }
    	}
    
    </script>
    //App.vue
    <template>
    	<button v-customOn:click="clicked">Click Me</button>
    <div style="width:100px;height:100px;" v-customOn = "mouseEnter">
    <div style="width:100px;height:100px;" v-customOn = "mouseLeave">        
    </div>
    </template>