使用工具类实现
1. 新建util.js
// 防抖
const mydebounce = (fn, delay, immediate = false) => {
let timer = null
let isInvoke = false
const _debounce = function(...args) {
if (timer) clearTimeout(timer)
if (!isInvoke && immediate) {
fn.call(this, args)
isInvoke = true
return
}
timer = setTimeout(() => {
fn.call(this, args)
timer = null
isInvoke = false
}, delay)
}
_debounce.cancel = function() {
if (timer) clearTimeout(timer)
timer = null
isInvoke = false
}
return _debounce
}
// 节流
const myThrottle = (fn, interval, immediate = true) => {
let startTime = 0
const _throttle = function(...args) {
const nowTime = new Date().getTime()
if (!immediate && startTime === 0) {
startTime = nowTime
}
const waitTime = interval - (nowTime - startTime)
if (waitTime <= 0) {
fn.apply(this, args)
startTime = nowTime
}
}
return _throttle
}
export default {
mydebounce,
myThrottle
}
2:页面内使用
示例:使用防抖处理resize监听
import util from '@/utils/util.js'
// 接收防抖函数
const cancalDebounce = util.mydebounce(initCanvas, 500)
// 页面卸载时去掉事件
onUnmounted(() => {
window.removeEventListener('resize', cancalDebounce);
})
onMounted(() => {
window.addEventListener('resize', cancalDebounce)
})
自定义指令实现
1:新建tools.js
export const toolsFunc = (app) => {
/*
* @Descripttion: 防抖,单位时间内触发最后一次
* @param [function] func --执行事件
* @param [?number|300] wait = 300 -- 时间间隔
* @param [?string|"click"] event -- 事件类型
* @param [?boolean|true] boolean -- 事件冒泡-false , 事件捕获--true
* @param [Array] binding.value - [func,type,wait,true]
* <a-button v-debounce="[func,'click',1000,true]">防抖测试</a-button>
*/
app.directive('debounce', {
beforeMount(el, binding) {
let [
func,
type = 'click',
wait = 300,
immediate = true
] = binding.value;
let timer = null
el.$type = type;
el.$handle = () => {
timer && clearTimeout(timer)
timer = setTimeout(() => func(), wait)
}
el.addEventListener(el.$type, el.$handle, immediate);
},
unmounted(el) {
el.removeEventListener(el.$type, el.$handle);
}
})
/*
* @Descripttion: 节流,单位时间内可触发一次
* @param [function] func --执行事件
* @param [?number|300] wait = 300 -- 时间间隔
* @param [?string|"click"] event -- 事件类型
* @param [?boolean|true] boolean -- 事件冒泡-false , 事件捕获--true
* @param [Array] binding.value - [func,type,wait,true]
* <a-button v-throttle="[func,'click',1000,true]">防抖测试</a-button>
*/
app.directive('throttle', {
beforeMount(el, binding) {
let [
func,
type = 'click',
wait = 300,
immediate = true
] = binding.value;
let timer = null
let timer_end = null
el.$type = type;
el.$handle = () => {
if (timer) {
clearTimeout(timer_end)
return timer_end = setTimeout(func, wait)
}
func()
timer = setTimeout(() => null, wait);
}
el.addEventListener(el.$type, el.$handle, immediate);
},
unmounted(el) {
el.removeEventListener(el.$type, el.$handle);
}
})
}
2:添加全局导入
import { tools } from './directives/tools.js'
const app = createApp(App)
tools(app)
3:页面使用
已节流为例,onUp为click事件的名称,防抖事件使用方式相同
<img src="" class="yt_img yt_t" v-throttle="[onUp,'click', 10]" />