一线大厂常用的六大vue自定义指令合集之防抖v-debounce

前言

截至目前,一线大厂常用的6大vue自定义指令中,我们已经学习实现了2个了,今天我们一起来看一下第三个常用的自定义指令防抖v-debounce。
关于javascript中是如何实现防抖,这里不再过多赘述,感兴趣的小伙伴可以查看这篇web前端高级JavaScript - 函数的防抖和节流文章了解更多。本篇文章主要介绍如何实现一个防抖的自定义指令,下面我们就来分析一下大体实现思路。

思路分析

  • 我们知道一般情况下,防抖函数会接收3个参数:一个是防抖函数中要执行的具体函数func,一个是等待的时间wait,还有一个就是immediate标识立即执行还是最后执行。
    之前学习vue自定义指令时我们已经知道:指令等号后面值会作为参数传递给指令函数,但是等号后面只有一个值,而我们要传递是3个值甚至更多,怎么办,其实也简单,我们只需要把要传递的参数拼成一个对象传递就可以了。这样传多少个参数都不是问题
  • 另外像wait和immediate这两个参数算是特殊参数,为什么这么说呢?wait是设置防抖时间的而immediate是作为标识的。这个时候冒号和修饰符就派上用场了。我们在使用vue指令的时候,在指令的后面可以跟一个冒号和一个值,而这个值也会被传给指令函数,并在函数中通过binding.arg或者这个值。同时指令后面还可以接修饰符,类似v-xxx.yyy,点后面的就是修饰符,在指令函数中通过binding.modifier.yyy获取该指令(一般是true或false值)
  • 通过上面的分析,其中的两个参数我们已经通过冒号和修饰符的形式传递了,那么就只剩下一个函数了,这个时候我们完全可以不用传递对象而是直接将函数传给指令即可。所以这里就出现了两种情况,一种是传递了一个对象,还有一种是只穿一个函数。所以后面我们写代码时应该有所区分,如果是函数直接执行,如果是对象则需要解析出对象中的值。
  • 另外为了让我们的自定义指令更灵活更通用,我们还需要做如下处理
    • 在指令函数中再额外接收一个type参数,用来标识是什么类型的防抖,比如click或scroll等,这个可以自由选择
    • 同时也接收一个额外的params参数。想想如果我们传递给指令的函数也需要其它参数呢,这时仍然可以通过外面以对象属性的形式进行传递
    • 最后就是除了函数是必须要传的参数以外,其它几个参数可以传也可以不传,所以我们需要为这些除了func以外的其它参数设置默认值。
  • 通过上面的思路分析,我想我们的防抖基本上已经差不多了。接下来就让我们来一起实践一下。

防抖v-debounce自定义指令代码

function debounce(func, wait = 300, immediate = true){
    
    
	let timer = null;
	return function anonymouse(...params){
    
    
		clearTimeout(timer);
		let now = immediate && !timer;
		timer = setTimeout(() => {
    
    
			timer = null;
			!immediate ? func.call(this, ...params) : null;
		},wait);
		now ? func.call(this, ...params) : null;
	}
}

const app = createApp();
app.directive("debounce",{
    
    
	beforeMount(el,binding){
    
    
		let val = binding.value,//获取指令传递的参数
			wait = 500,//wait默认500毫秒
			immidiate = false,
			type = 'click',
			params = [],
			func
		if(val == null) return;//如果没有传递任何参数则什么也不做
		if(typeof val !== 'object' && typeof val !== 'function') return ;//如何传递的参数既不是对象也不是函数则也什么都不做
		if(binding.arg) wait = +binding.arg;//获取冒号后面的参数
		if(binding.modifiers && binding.modifiers.immediate) immediate = binding.modifiers.immediate;//获取修饰符
		if(typeof val === 'function') func = val;//如果传递的是函数则直接赋给func
		if(typeof val === 'object'){
    
    //如果是对象则对对象进行解析
			func = val.func || function(){
    
    };
			type = val.type || 'click';
			params = val.params || [];			
		}
		el.$type = type;
		//此步操作多定义了一个proxy函数目的是可以给func传递参数,同时保证func中的this指向
		el.$handle = debounce(function proxy(...args){
    
    
			return func.call(this, ...params.concat(args));
		},wait, immediate);
		el.addEventListener(el.$type, el.$handle);
	},
	unmounted(el){
    
    
		el.removeEventListener(el.$type, el.$handle);
	}
});

总结

如此我们便实现了一个防抖的自定义指令,该指令相较于前两个指令有些复杂,涉及到的代码也是有点多的。但比起前两个来说也是更常用的。下篇文章中我们将一起研究下一个常用节流自定义指令。
好了本文就介绍到这里,有任何问题欢迎指正。同时喜欢的小伙伴欢迎点赞留言加关注哦!

猜你喜欢

转载自blog.csdn.net/lixiaosenlin/article/details/120568767
今日推荐