1. 描述:

  • 本文章是在vue2项目中对防抖 节流函数进行封装

2. .vue文件代码示例

<template>
	<div>
		<div>
			<button @click="antiShake('防抖')">防抖</button>
			<button @click="throttling('节流')">节流</button>
		</div>
	</div>
</template>
<script>
//引入js文件(js文件代码在该部分代码之后)
import { debounce, throttle} from '@/toolStation/statice.js'
export default {
	data() {
		return {
		}
	},
	mounted() {
	},
	methods: {
		// 事件触发
		//防抖
		antiShake: debounce(function (...args) {
			this.antiShakeBtn(...args)
		}, 1000, true),
		//节流
		throttling: throttle(function (...args) {
			this.throttlingBtn(...args)
		}, 1000),
        
		// 防抖、节流功能函数
		antiShakeBtn(val) {
			//写按钮功能
			console.log(val);
		},
		throttlingBtn(val) {
			//写按钮功能
			console.log(val);
		},
	}
}
</script>
<style lang="less" scoped>
</style>

3. . js文件代码示例

// 防抖
export const debounce = (fn, delay) => {
	var time = null
	return function() {
		let context = this;//记录一下this指向
		let args = arguments;
		//清除定时任务
		if (time) clearTimeout(time);
		time = setTimeout(function() {
			time = null;
			fn.apply(context, args)
		}, delay)
	}
}
// ps:!!!!!!!!防抖扩展---第三个参数控制第一次点击是否立即执行,
// export const debounce = (fn, delay, immediate) => {
// 	var time = null
// 	return function() {
// 		let context = this;//记录一下this指向
// 		let args = arguments;
// 		//清除定时任务
// 		if (time) clearTimeout(time);
// 		// 第一次点击是否立即执行
// 		if (immediate) {
// 			fn.apply(context, args)
// 			immediate = false;

// 			// 超过delay时间immediate重置为true 
// 			time = setTimeout(function() {
// 				time = null;
// 				immediate = true;
// 			}, delay)
// 		} else {
// 			time = setTimeout(function() {
// 				time = null;
// 				fn.apply(context, args)
// 			}, delay)
// 		}
// 	}
// }

// 节流
export const throttle=(fn, delay) => {
	// 时间戳
	var timeTwo = 0 //new Date();
	// 定时器
	var timeThree = null;
	return function() {
		let context = this;
		let args = arguments;
		var now = new Date()

		// !!!!时间戳实现【new Date()虽然获取结果不是时间戳但是计算结果会自动转化为时间戳】
		// if(now-timeTwo>=delay){
		//     fn.apply(context,args);
		//     timeTwo=new Date();
		// }

		// !!!!定时器实现
		// if (!timeThree) {
		//     timeThree = setTimeout(function () {
		//         fn.apply(context, args);
		//         timeThree=null;
		//     }, delay)
		// }

		// 结合 ps:最后一次触发在固定频率内会在延迟后触发
		var wait = delay - (now - timeTwo)
		clearTimeout(timeThree)
		if (wait <= 0) {
			fn.apply(context, args);
			timeTwo = new Date();
		} else {
			timeThree = setTimeout(function() {
				fn.apply(context, args);
			}, delay)
		}
	}
}

4. 总结:

4.1 防抖

  • 当事件触发时,相应的函数并不会立即触发,而是会等待一定的时间;当事件密集触发时,函数的触发会被频繁的推迟;只有等待了一段时间也没有事件触发,才会真正的执行响应函数
  • 场景:input输入等等.

4.2 节流

  • 当事件触发时,会执行这个事件的响应函数; 如果这个事件会被频繁触发,那么节流函数会按照一定的频率来执行函数; 不管在这个中间有多少次触发这个事件,执行函数的频繁总是固定的
  • 场景:多次点击等等.

4.3 .vue文件点击事件函数写法解释:(来源于chatgpt)

  • antiShake方法:
    通过 debounce 的帮助,将 antiShakeBtn 方法进行“防抖”封装。即函数被调用时,如果在规定的时间内该函数被再次调用,则取消上一次的调用,以保证方法不会被多次调用。与普通的写法相比,防抖函数在短时间内只能被触发一次,从而节省内存开销,避免不必要的多次调用。
  • throttling方法:
    通过 throttle 的帮助,将 throttlingBtn 方法进行“节流”封装。即函数在一段时间内只能被调用一次,让数据处理函数在一段时间内只执行一次,从而有效的控制函数的执行频率。与普通的写法相比,节流函数可以控制函数在一段时间内只能被触发一次,从而节省内存开销,避免不必要的过度调用。

4.4 补充

  • js代码中还有很多优化的地方比如使用箭头函数解决this。
  • 下面是防抖使用箭头函数的简单优化,使用方式不变。
export const debounce = (func, delay) => {
  let timeId = null
  return function (...args) {
    clearTimeout(timeId);
    timeId = setTimeout(() => {
      func.apply(this, args);
    }, delay);
  };
};
Logo

前往低代码交流专区

更多推荐