使用防抖与节流,及this指向问题
最近项目中遇到了防抖与节流问题,搜索了很多文章都有this指向的问题,最后不得不采取一种很low的方法
data中定义isFirst为1
if (this.isFirst < 2){ this.isFirst = 2 setTimeout(() => { this.isFirst = 1 }, 1000) }
这样就形成了假的节流
但是我们怎么能屈服于这种写法
继续探索vue项目中用闭包的方式防抖节流
一顿操作后
const delay = (function () { let timeout return (callback, ms) => { if (timeout) clearTimeout(timeout) let callNow = !timeout timeout = setTimeout(() => { timeout = undefined }, ms) if (callNow) callback.apply(this, [callback, ms]) } })() export default { methods: { delay(() => { // do something }, 1000) } }
用了立即执行的函数方法,就能够获取到全局的this了
使用防抖函数所遇见的坑
以前的防抖和节流都是在js中直接书写,后使用vue进行组件化开发之后,有些地方需要注意。
正常写法
function debounce(func, delay) { let timeout return function () { let context = this; let args = arguments; if (timeout) { clearTimeout(timeout) } timeout = setTimeout(() => { func.apply(context, args) }, delay) } }
使用
function change(volume, data) { debounce(() => { console.log('change', volume, data); }, 500) }
Vue中写法使用
注意: Vue中使用时,需要定义timeout,同时在防抖函数中,this的指向发生了变化,需要在return之前获取vue实例。这个时候,你直接使用,还是不行的,只要debug就会发现debounce返回的func没有进去,需要手动执行一下(添加括号)。
data() { return { timeout: null } }
change(volume, data) { this.debounce(() => { console.log('change', volume, data) }, 500) }, debounce(func, delay) { let context = this // this指向发生变化,需要提出来 let args = arguments return function () { if (context.timeout) { clearTimeout(context.timeout) } context.timeout = setTimeout(() => { func.apply(context, args) }, delay) }()// 注意:我加了() }
Vue中的watch的防抖简写
watchObj: { handler(val) { let _this = this clearTimeout(this.timeout) this.timeout = setTimeout(() => { _this.handlerData(val) }, 500) } }
以上为个人经验,希望能给大家一个参考,也希望大家多多支持阿兔在线工具。