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() } } }