前端排坑指南(二)
vue使用防抖节流
目前开发发现很多同事都知道防抖节流,但不知道如何在vue工程上使用,实现。所以就发布一篇自己学习总结的方法。
当您读这篇文章时,默认您已经了解什么是防抖节流了。
痛点:
使用vue开发项目,如果是使用vue-cli,就会出现使用.vue
的文件进行页面开发。
然后我们定义在methods
里的方法,使用封装的防抖节流高阶函数包裹时,就出现不生效的效果。
原因:
因为methods
里的函数因双向绑定的影响,导致无法闭包。就不断刷新函数。
解决:
computed
计算数据有缓存数据的功能,这样是它和``watch`的较大不同点之一,我们就可以利用这个属性,完成函数的闭包,实现防抖节流高阶函数包裹操作函数。
实现案例:
<script>
/**
* 防抖高阶函数
* 多次点击只触发最后一次,最后一次倒计时完成后执行
* 倒计时内无法触发执行
*
* @param { Object } object // { fn(执行函数), delay(延时时间), that(指定this) }
* @return { Function } // 返回过滤函数,计时后执行fn
*/
export function debounce({ fn, delay = 1000, that = null }) {
let timer = null
return function () {
if (timer !== null) clearTimeout(timer)
timer = setTimeout(() => {
let _this = this
if (that) _this = that
fn.apply(_this, arguments)
}, delay)
}
}
/**
* 节流高阶函数
* 多次点击, 只触发第一次,第一次倒计时完成后执行
* 倒计时内无法触发执行
*
* @param { Object } object // { fn(执行函数), delay(延时时间), that(指定this) }
* @return { Function } // 返回过滤函数,并执行fn
*/
export function throttle({ fn, delay = 1000, that = null }) {
let preTime = null
return function () {
if (!preTime) {
preTime = setTimeout(() => {
let _this = this
if (that) _this = that
fn.apply(_this, arguments)
preTime = null
}, delay)
}
}
}
/**
* 首次触发高阶函数
* 多次点击,只执行第一次,第一次立刻执行,然后开始倒计时。
* 倒计时内无法触发执行
*
* @param { Object} object // { fn(执行函数), delay(延时时间), that(指定this) }
* @returns { Function } // 返回过滤函数,计时后执行fn
*/
export function firstTrigger({ fn, delay, that }) {
let proTime = +new Date()
let timer = null
let theDelay = delay
return function () {
let nowTime = +new Date()
if (timer !== null) clearTimeout(timer)
theDelay = delay + proTime - nowTime
timer = setTimeout(() => {
let _this = this
if (that) _this = that
fn.apply(_this, arguments)
proTime = nowTime
}, theDelay)
}
}
export default {
render(h) {
return h('div', null, [
h(
'button',
{
on: {
click: () => {
this.computedHandle(this.sum)
}
}
},
'多次点击, 只触发最后一次'
),
h(
'span',
{
style: {
margin: '6px'
}
},
this.sum
)
])
},
data() {
return {
sum: 0
}
},
computed: {
// 使用计算属性,返回操作函数
computedHandle() {
return debounce({ fn: this.handle, delay: 300, that: this })
}
},
methods: {
handle(sum) {
this.sum++
console.log(sum)
}
}
}
</script>