在React、Vue和小程序中使用函数节流和函数防抖
在上一篇中我总结了节流函数和防抖函数的基本原理:总结前端函数防抖与函数节流。接下来介绍一下防抖函数和节流函数在前端框架中的使用。在使用前一定要注意两个问题:this的指向事件对象的传递React中使用防抖函数和节流函数...
·
在上一篇中我总结了节流函数和防抖函数的基本原理:总结前端函数防抖与函数节流。
接下来介绍一下防抖函数和节流函数在前端框架中的使用。
在使用前一定要注意两个问题:
- this的指向
- 事件对象的传递
React中使用防抖函数和节流函数
在React事件调用时,React传递给事件处理程序是一个合成事件对象的实例。SyntheticEvent
对象是通过合并得到的。 这意味着在事件回调被调用后,SyntheticEvent 对象将被重用并且所有属性都将被取消
。 这是出于性能原因。 因此,您无法以异步方式访问该事件
。
React合成事件官方文档
//React无法异步访问事件对象
function onClick(event) {
console.log(event); // => nullified object.
console.log(event.type); // => "click"
const eventType = event.type; // => "click"
setTimeout(function() {
console.log(event.type); // => null
console.log(eventType); // => "click"
}, 0);
// 不能工作。 this.state.click 事件只包含空值。
this.setState({clickEvent: event});
// 您仍然可以导出事件属性。
this.setState({eventType: event.type});
}
所以在用防抖或节流函数封装时,异步方式访问事件对象出现问题。解决的方法如下:
- 方法一:调用合成事件对象的persist()方法
- 方法二:深拷贝事件对象
function debounce(func, wait=500) {
let timeout; // 定时器变量
return function(event){
clearTimeout(timeout); // 每次触发时先清除上一次的定时器,然后重新计时
event.persist && event.persist() //保留对事件的引用
//const event = e && {...e} //深拷贝事件对象
timeout = setTimeout(()=>{
func(event)
}, wait); // 指定 xx ms 后触发真正想进行的操作 handler
};
}
class Test extends React.Component{
handleChange = debounce((e)=>{
console.log(e.type)
console.log(this)
})
render(){
return (
<div>
<input type="text" onChange={this.handleChange}/>
</div>
)
}
}
在Vue中使用防抖函数和节流函数
<div id="app">
<input type="text" @keydown="handleChange">
</div>
<script>
function debounce(func, wait=500) {
let timeout; // 定时器变量
return function(event) {
clearTimeout(timeout); // 每次触发时先清除上一次的定时器,然后重新计时
timeout = setTimeout(()=>{
console.log(123,this)
func.call(this,event)
}, wait); // 指定 xx ms 后触发真正想进行的操作 handler
};
}
new Vue({
el: '#app',
methods: {
handleChange:debounce(function(e){
console.log(e)
console.log(this)
})
}
})
</script>
在小程序中使用防抖函数和节流函数
<input bindinput='change' style='border:1px solid #000;'></input>
function debounce(func, wait = 500) {
let timeout;
return function (event) {
clearTimeout(timeout);
timeout = setTimeout(() => {
func.call(this, event)
}, wait);
};
}
Page({
change: debounce(function(e){
console.log(e)
console.log(this)
})
})
总结
上面this的指向涉及了复杂的知识点:箭头函数、闭包、class方法的this、事件调用、call等。单个理解这些知识点并不是很难,但是组合在一起后,理解就很困难了。目前自己对上面框架中防抖函数的this指向还不清楚,自己只是在代码中试错来理解this。
更多推荐
已为社区贡献5条内容
所有评论(0)