假设一个场景:比如你快速点击一个按钮的时候,你会发现,无论你点击的有多快,只要点击了一次,日志就会打印一次;
防抖:如果短时间内大量触发同一事件,只会执行一次函数。
需求---在快速点击的过程中,如何只让最后一次点击能产生效果。(使用lodash中的debounce方法实现)
节流:如果短时间内大量触发同一事件,那么函数在执行一次之后,该函数在指定的时间内不在工作,直至过了这段时间才重新生效。
需求---在快速点击的过程中,如何降低一下日志打印的频率,比如1s内最多执行一次。(使用lodash中的throttle方法)
节流和防抖 节流 防抖 场景 1.有些事件是会频繁触发的,比如:keyup(键盘的点击)、scroll(滚动)、resize(屏幕窗口的变化)、mousemove(鼠标的移动)等等。
2.我依然想让它频繁触发事件:只不过不要那么频繁就好
1.有些事件是会频繁触发的,比如:keyup(键盘的点击)、scroll(滚动)、resize(屏幕窗口的变化)、mousemove(鼠标的移动)、搜索框联想建议等等。
2.我不想让它如此频繁触发事件:只需要在最后一次事件做操作即可
实现步骤 在产生事件时,判断节流阀,如果节流阀成立,立马将节流阀设置为不成立,然后做正常操作,开启新的定时器,定时器结束时重置节流阀 在产生事件时,取消上一次定时器,开启新的定时器 区别 1.一段时间内,可能会产生多次效果,只不过每一次之间的频率降低了
2.在意过程
1.一段时间内,只有最后一次产生效果
2.不在意过程
相同点 都是为了降低频率
节流和防抖在Vue项目中的使用
第一步:创建utils.js
utils.js /** *【防抖】 * 1.设置一个定时器 * 2.设置一个闭包,返回一个方法 * 3.如果反复进来,清空前面的定时器 * 4.再重新设置一遍定时器 */ export function debounce(fn, delay) { let timer = null; //1.设置一个定时器 return function() { //2.设置一个闭包,返回一个方法 let _that = this; //保存执行上下文的this let args = arguments; //保存传入的参数 if (timer) { clearTimeout(timer); //3.每次事件触发时,都去清除之前的旧定时器 } //4.设立新定时器 timer = setTimeout(() => { fn.apply(_that, args); }, delay) } } /** * 【节流】 * 思路:每次点击的时候,用现在的时间和上一次点击的时间作比较, * 如果大于传入的时间,则执行传入的代码,否则不执行。 * fn:需要节流的回调函数 * delay:毫秒,计时器,节流期限值,传入的时间,多少时间后执行 */ export function throttle(fn, delay) { let last = 0; //记录上一次执行回调函数的时间 return function() { let _that = this; let args = arguments; let now = +new Date(); //加'+'表示转化为时间戳 if ((now - last) > delay) { last = now; //保存该次执行的时间 fn.apply(_that, args); } } //开启阀门:这种写法也可以 // let flag = true; // return function (){ // let _that = this; // let args = arguments; // if(flag){ // flag = false; // setTimeout(() => { // flag = true; // fn.apply(_that, args); // },delay) // } // } } /** *【防抖+节流】 * 防抖有时候因为触发太过频繁,导致一次响应都没有, * 所以希望固定的时间必定给用户一个响应,于是就有了防抖+节流的操作。 * 1.设置last记录定时器开始的时间 * 2.设置timer表示一个定时器 * 3.获取当前时间now * 4.如果当前时间 - 开始时间小于延迟时间,那么就防抖 * 5。否则设置时间到了,执行函数 */ export function debounceThrottle(fn, delay) { let last = 0; let timer = null; return function() { let _that = this; let args = arguments; let now = +new Date(); if ((now - last) < delay) { clearTimeout(timer); timer = setTimeout(() => { last = now; fn.apply(_that,args); },delay) }else{ last = now; fn.apply(_that,args); } } }
第二步:在Vue组件中引入并使用
<template> <div class="home"> <div @click="handleClick" style="cursor: pointer;">首页</div> </div> </template> <script> import {debounce,throttle} from '../utils/utils.js'//第一种方法:方法引入 import _ from 'lodash'//第二种方法:使用 lodash 插件 export default { data() { return {} }, methods: { //第一种方法:方法引入 handleClick:debounce(function(){ console.log('防抖'); },3000), handleClick:throttle(function(){ console.log('节流'); },3000) //第二种方法:使用 lodash 插件 handleClick:_.debounce(function(){ console.log('lodash:防抖'); },3000), handleClick:_.throttle(function(){ console.log('lodash:节流'); },3000) }, created() { } } </script>