vue.js如何实现节流和防抖,所谓防抖,就是指触发事件后,就是把触发非常频繁的事件合并成一次去执行。即在指定时间内只执行一次回调函数,如果在指定的时间内又触发了该事件,则回调函数的执行时间会基于此刻重新开始计算。
应用场景:
在一个电影项目中,我想在电影的列表中,保存下拉的当前位置,防止你切换页面后,再切换回当前的电影列表页,他就又回到电影的第一条数据。
这时候,我不想每次只要滑动一点,就保存当前位置,我想隔一段时间,保存一次,这时候,就可以使用防抖和节流。
概念:
防抖是延迟执行,而节流是间隔执行,函数节流即每隔一段时间就执行一次,实现原理为 设置一个定时器,约定XX毫秒后执行事件,如果时间到了,那么执行函数并重置定时器,和防抖的区别在于,防抖每次触发事件都重置定时器,而节流在定时器到时间后再清空定时器。
函数防抖的情况下,函数将一直推迟执行,造成不会被执行的效果;
函数节流的情况下,函数将每个 n 秒执行一次。
节流
/**
* 节流:在一定时间内,只能触发一次
*
* @param {func} func 要执行的回调函数
* @param {Number} delay 延时的时间
* @param {Boolean} immediate 是否立即执行
* @return null
*/
export const throttle =(func,delay)=>{
var timer = null;
return function() {
var context = this;
var args = arguments;
if (!timer) {
timer = setTimeout(function() {
func.apply(context, args);
timer = null;
}, delay);
}
}
}
防抖
/**
* 防抖:一定时间内,只有最后一次操作,再过wait毫秒后才执行函数
*
* @param {func} func 要执行的回调函数
* @param {Number} delay 延时的时间
* @param {Boolean} immediate 是否立即执行
* @return null
*/
export const debounce = (func, wait = 500, immediate = false) => {
let timeout = null;
return function() {
let context = this;
let args = arguments;
if (timeout) clearTimeout(timeout);
if (immediate) {
var callNow = !timeout; //点击第一次为true 时间内点击第二次为false 时间结束则重复第一次
timeout = setTimeout(() => {
timeout = null;
}, wait); //定时器ID
if(callNow) func.apply(context, args);
}
else
{
timeout = setTimeout(function() {
func.apply(context, args);
}, wait);
}
}
}
调用:
import { debounce } from '@/libs/tools'
search:debounce(function(){
console.log('防抖立即执行');
this.reload();
},600),
或者以下:
// utils.js
// immediate 是否开始立即执行
function debounce(func, delay = 300, immediate = false) {
let timer = null
return function() {
if (timer) {
clearTimeout(timer)
}
if (immediate && !timer) {
func.apply(this, arguments)
}
timer = setTimeout(() => {
func.apply(this, arguments)
}, delay)
}
}
防抖在vue中使用
方法一:写在公共方法utils里引入
import { debounce } from 'utils'
methods: {
appSearch:debounce(function(e.target.value){
this.handleSearch(value)
}, 1000),
handleSearch(value) {
console.log(value)
}
}
方法二:写在当前vue文件中
data: () => {
return {
debounceInput: () => {}
}
},
methods: {
showApp(value) {
console.log('value', value)
},
debounce(func, delay = 300, immediate = false) {
let timer = null
return function() {
if (timer) {
clearTimeout(timer)
}
if (immediate && !timer) {
func.apply(this, arguments)
}
timer = setTimeout(() => {
func.apply(this, arguments)
}, delay)
}
}
},
mounted() {
this.debounceInput = this.debounce(this.showApp, 1000)
},
使用方法与防抖相同
节流:频繁操作稀释函数执行,频繁操作时,每隔n秒才触发一次
使用场景
鼠标点击,mousedown,mousemove单位时间只执行一次
滚动事件,懒加载、滚动加载、加载更多或监听滚动条位置
防止高频点击提交,防止表单重复提交
// utils.js
function throttle (func, delay = 300) {
let prev = 0
return function() {
let now = Date.now()
if ((now - prev) >= delay) {
func.apply(this, arguments)
prev = Date.now()
}
}
}


