防抖:字面意思,怕多次提交,定时(定时2S 中调用后,重新刷新定时器 2S)
节流:字面意思,防止提交频率过快,但还是要提交,定时(每2秒提交提交一次,中间不管你点了多少次 。间隔时间 = 延迟的时间 - (结束时间戳 - 开始时间戳) )
一、js方式
export default {
// 防抖
debounce: function (fn, delay) {
// 时间期限
var delays = delay || 200
var timer
// 闭包
return function () {
// 考虑作用域,上下文环境,apply需要用到this对象
var th = this
// 接收的参数用 ES6 中的 rest 参数统一存储到变量 args 中。arguments就是传入的参数数组,而且个数可以不确定的传回给fn(不确定函数到底有多少个参数,用arguments来接收)
var args = arguments
// 判断还在定时,说明当前正在一个计时过程中,并且又触发了相同事件。所以要取消当前的计时,重新开始计时
if (timer) {
clearTimeout(timer)
}
timer = setTimeout(function () {
timer = null
// 执行方法
fn.apply(th, args)
}, delays)
}
},
// 节流 定时器 + 时间戳
throttle: function(func, delay) {
var timer = null
var startTime = Date.now()
return function() {
// 结束时间
var curTime = Date.now()
// 间隔时间 = 延迟的时间 - (结束时间戳 - 开始时间戳)
var interval = delay - (curTime - startTime)
var th = this
var args = arguments
clearTimeout(timer)
if (interval <= 0) {
// 证明可以触发了
func.apply(th, args)
// 重新计算开始时间
startTime = Date.now()
} else {
// 继续等待
timer = setTimeout(func, interval)
}
}
}
}
import antiShake from '@/utils/antiShake.js' // 防抖节流
methods: {
refresh: antiShake.throttle(function () {
// 需要防抖的内容
that.fetch()
}, 2000),
// 关闭操作
close() {
if (this.visible) {
this.visible = false
this.$refs.form.resetFields()
}
if (this.sampleVisible) {
this.sampleVisible = false
this.$refs.sampleVisible.resetFields()
}
},
that.fetch() 用this会报错,但是能使用
全局定义个that
created() {
that = this
this.fetch()
},
二、指令
定义
Vue.directive('debounce',{
inserted:(el,binding)=>{
let delay= binding.args
if(!delay){
delay=1000
}
let time
el.addEventListener('input',()=>{
if(time){
clearTimeout(time)
}
time= setTimeout(()=>{
binding.value()
},delay)
})
}
})
Vue.directive('throttle',{
inserted:(el,binding)=>{
let delay =binding.args
if(!delay) delay=1000
let time =null
el.addEventListener('input',()=>{
if(!time){
time=setTimeout(()=>{
binding.value()
time=null
},delay)
}
})
}
})
使用
<template>
<button v-debounce:1000="debounceClick">防抖</button>
</template>
<script>
export default {
methods: {
debounceClick () {
console.log('只触发一次')
}
}
}
</script>
<template>
<button v-throttle:1000="debounceClick">防抖</button>
</template>
<script>
export default {
methods: {
debounceClick () {
console.log('只触发一次')
}
}
}
</script>
三、插件
npm install throttle-debounce --save
import { throttle } from ‘throttle-debounce’;
throttleCallback: throttle(1000, false, () => {
//业务
}),
debounceCallback: debounce(1000, false, () => {
//业务
}),