防抖和节流可以通过使用 Lodash 库中的 debounce
和 throttle
方法来实现。
防抖(debounce) 是指在一定时间内,如果事件持续触发,则只执行最后一次事件。常用于输入框搜索、滚动加载等场景。 回城
节流(throttle) 是指在一定时间内,无论事件触发多少次,只执行一次事件。常用于滚动事件、窗口大小改变等场景。普攻
一、方法封装
javascript
export const debounce = (fn, delay = 0, immediate = false) => {
let timeout;
return (...args) => {
if (immediate && !timeout) fn(...args);
clearTimeout(timeout);
timeout = setTimeout(() => {
fn(...args);
}, delay);
};
};
// 节流函数
export const throttle = (func, delay) => {
let timeoutId;
let lastExecTime = 0;
return function (...args) {
const currentTime = Date.now();
if (currentTime - lastExecTime < delay) {
// 上次执行时间距当前时间未超过指定延迟,不执行函数
clearTimeout(timeoutId);
timeoutId = setTimeout(() => {
lastExecTime = currentTime;
func.apply(this, args);
}, delay);
} else {
// 上次执行时间距当前时间已超过指定延迟,立即执行函数
lastExecTime = currentTime;
func.apply(this, args);
}
};
}
或者
javascript
/**
* @desc 函数防抖
* @param func 目标函数
* @param wait 延迟执行毫秒数
* @param immediate true - 立即执行, false - 延迟执行
*/
export const debounce = function(func, wait = 1000, immediate = true) {
let timer;
console.log(1);
return function() {
console.log(123);
let context = this,
args = arguments;
if (timer) clearTimeout(timer);
if (immediate) {
let callNow = !timer;
timer = setTimeout(() => {
timer = null;
}, wait);
if (callNow) func.apply(context, args);
} else {
timer = setTimeout(() => {
func.apply(context, args);
}, wait)
}
}
}
/**
* @desc 函数节流
* @param func 函数
* @param wait 延迟执行毫秒数
* @param type 1 使用表时间戳,在时间段开始的时候触发 2 使用表定时器,在时间段结束的时候触发
*/
export const throttle = (func, wait = 1000, type = 1) => {
let previous = 0;
let timeout;
return function() {
let context = this;
let args = arguments;
if (type === 1) {
let now = Date.now();
if (now - previous > wait) {
func.apply(context, args);
previous = now;
}
} else if (type === 2) {
if (!timeout) {
timeout = setTimeout(() => {
timeout = null;
func.apply(context, args)
}, wait)
}
}
}
}
二、操作案例
点击事件使用节流的思路(vue2的节流方法)
html:
html
<view class="time">
<uni-datetime-picker
v-model="valueTwoTimer"
type="daterange"
rangeSeparator="至"
@change="changeTime"
/>
<button @click="handleClickLook">搜索</button>
</view>
js:
javascript
import { throttle } from 'lodash'
export default {
data() {
return {
scrollHeight: 0
}
},
mounted() {
// 监听滚动事件
window.addEventListener('scroll', this.handleScroll)
},
beforeDestroy() {
// 移除滚动事件监听
window.removeEventListener('scroll', this.handleScroll)
},
methods: {
// 节流函数
handleScroll: throttle(function() {
this.scrollHeight = window.scrollY
console.log(this.scrollHeight)
// 执行滚动操作
}, 500)
//查看按钮功能
handleClickLook: throttle(function () {
this.isFinish = 1;
this.getInteilEnergyHisDatas(); //1.整体油耗
this.getfuilOilInfo(); //2.燃油舱
}, 3000),
}
}
点击事件使用节流的思路(vue3)
html:
html
<el-button
class="hdtbutton look"
@click="handleClickLook"
>
查询
</el-button>
js:
javascript
import { getAssetsFile, throttle } from "@/utils";
const handleClickLook = throttle(async () => {
data.isFinish = 1;
data.isTips = "加载中...";
let info = {
startTime: data.valueTwoTimer[0],
endTime: data.valueTwoTimer[1],
};
// const resApiData = await getInteilEnergyTotal(info); //接口数据
const resApiData = false;
console.log("resApiData>>>", resApiData);
if (resApiData === false) {
delayTimer = setTimeout(() => {
data.isFinish = 2;
data.isTips = "暂未接入";
}, data.btnDelay);
return;
} else {
if (resApiData.length && resApiData.length !== 0) {
data.isFinish = 4;
data.isTips = "接口数据获取成功";
} else {
data.isFinish = 3;
data.isTips = "暂无数据";
ElMessage({
type: "warning",
message: "暂无数据!",
});
}
}
}, 3000);
其它,