在main.js
中全局注册组件Debounce
// 防抖节流
import Debounce from './debounce.js'
Vue.component('Debounce', Debounce)
组件核心代码debounce.js
// debounce.js
/**
* 防抖与节流
* @param {function} func 执行函数
* @param {number} time 防抖节流时间
* @param {string} type debounce为防抖,throttle为节流,否则为立即执行
* @param {this} ctx this 的指向
*/
const debounce = (func, time, type, ctx) => {
var timer, lastCall, rtn
// 防抖函数
if (type === 'debounce') {
rtn = (...params) => {
if (timer) clearTimeout(timer)
timer = setTimeout(() => {
func.apply(ctx, params)
}, time)
}
} else if (type === 'throttle') {
// 节流函数
rtn = (...params) => {
const now = new Date().getTime()
if (now - lastCall < time && lastCall) return
lastCall = now
func.apply(ctx, params)
}
} else {
// 立即执行的防抖函数
rtn = (...params) => {
if (timer) clearTimeout(timer)
let callNow = !timer
timer = setTimeout(() => {
timer = null
}, time)
if (callNow) func.apply(ctx, params)
}
}
return rtn
}
export default {
name: 'Debounce',
abstract: true,
props: {
time: {
type: Number,
default: 1000,
},
events: {
type: String,
default: 'click', // 默认点击事件
},
type: {
type: String,
default: 'throttle', // 默认节流
},
},
created() {
this.eventKeys = this.events.split(',') // 分隔事件
this.originMap = {} // 储存事件,用于重新render时与子事件的对比
this.debouncedMap = {} // 储存防抖节流事件
},
render() {
try {
const vnode = this.$slots.default[0]
this.eventKeys.forEach(key => {
const target = vnode.data.on[key]
if (target === this.originMap[key] && this.debouncedMap[key]) {
vnode.data.on[key] = this.debouncedMap[key]
} else if (target) {
this.originMap[key] = target
this.debouncedMap[key] = debounce(target, this.time, this.type, vnode)
vnode.data.on[key] = this.debouncedMap[key] // 重写子组件的事件
}
})
return vnode
} catch (error) {}
},
}
组件使用
使用<Debounce></Debounce>
标签包裹按钮;
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。