1.首先,需要先寫好一個防抖函數或節流函數
// 防抖函數 export function debounce(fn, delay){ let timeout = null return function(){ let args = arguments if(timeout) window.clearTimeout(timeout) timeout = setTimeout(() => { fn.apply(this, args) }, delay) } } // 節流函數 export function throttle(fn, delay){ let timeout = null return function(){ let args = arguments if(!timeout){ timeout = setTimeout(() => { timeout = null fn.apply(this, args) }, delay) } } }
然后,在vue文件中引用,並調用:
methods: { handleClick(){ this.debounce(this) }, debounce: debounce((vm) => { // do something,這里this不指向Vue實例,用vm傳入 }, 1000), }
節流同理。
2.如果要在監聽某個事件的時候使用,這時候大致差不多:
mounted(){ let self = this window.addEventListener('scroll',this.scroll.bind(this, self)) }, methods: { scroll: throttle((self) => { // 用bind就可以給箭頭函數傳參,不用bind則這里不能用箭頭函數 var body = document.body // 獲取滾動條的dom var scrollTop = body.scrollTop || window.pageYOffset var windowHeight = body.clientHeight var scrollHeight = body.scrollHeight if(scrollTop+windowHeight>=scrollHeight){ self.scrollBottom = true }else{ self.scrollBottom = false } },300) }
這里需要注意的是this的指向,一般來說當函數內使用箭頭函數時此時函數內的this指向最近的函數this指向,即指向window,使用普通函數function時指向調用它的對象;
在addEventListener中有所不同,window.addEventListener('scroll') 中,一般來說箭頭函數指向最近的this指向,是window,普通函數指向調用它的對象,也是window;
但是在Vue中不是這樣,使用箭頭函數時,指向undefined,而普通函數指向 Vue實例, 我想原因在於這里的scroll是一個匿名函數,在Vue中是處於嚴格模式的,所以指向undefined,而普通函數則處在Vue實例中,所以指向Vue實例;
所以如果要使用箭頭函數,而且已知箭頭函數的指向不能被bind、call、apply改變,而函數內需要使用Vue實例,那么就可以考慮為函數傳參,在考慮這里只是需要傳參,不能執行函數,所以只能用bind,就如上代碼所示。
所以這里有兩種寫法,最后,別忘了在銷毀組件前移除事件監聽,否則會造成內存泄露。