最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

vue組件中節(jié)流函數(shù)的失效的原因和解決方法

 更新時間:2020年12月02日 09:19:11   作者:幻靈爾依  
這篇文章主要介紹了vue組件中節(jié)流函數(shù)的失效和解決方法,幫助大家更好的理解和學(xué)習(xí)vue框架,感興趣的朋友可以了解下

今天使用節(jié)流函數(shù)的時候遇見了一個問題,搞了半天才找到原因,所以在這里做個總結(jié)。

節(jié)流函數(shù)

瀏覽器的一些事件,如:resize,scroll,mousemove等。這些事件觸發(fā)頻率太過頻繁,綁定在這些事件上的回調(diào)函數(shù)會不停的被調(diào)用,加重瀏覽器的負擔(dān),導(dǎo)致用戶體驗非常糟糕。所以先賢們發(fā)明了節(jié)流函數(shù),簡單版本如下:

function throttle (f, wait = 200) {
 let last = 0
 return function (...args) {
 let now = Date.now()
 if (now - last > wait) {
  last = now
  f.apply(this, args)
 }
 }
}

假設(shè)有一個 vue 組件 svgMark。這個組件中渲染的元素要在頁面窗口大小發(fā)生變化時重繪 reDraw ,而重繪時要使用節(jié)流函數(shù)防止性能損耗。正常情況下代碼如下:

<template>
 <div>{{ index }}</div>
</template>

<script>
import { throttle } from 'lodash'
export default {
 name: 'SvgMark',
 data() {
 return {
  index: 0
 }
 },
 mounted() {
 window.addEventListener('resize', this.reDraw)
 },
 beforeDestroy() {
 window.removeEventListener('resize', this.reDraw)
 },
 methods: {
 reDraw: throttle(function() {
  this.index++
 }, 500)
 }
}
</script>
</script>

一般情況下這樣用沒什么問題。但是有這樣一個場景,使用節(jié)流函數(shù)時卻失效了,即當這個組件被 v-for 循環(huán)加載了很多次:

<template>
 <div>
 <svgMark v-for="item in 10" :key="item.id" />
 </div>
</template>

這個時候無論渲染了多少個 svgMark 組件,在窗口大小改變的時候卻只觸發(fā)了第一個組件和第 n 割組件的重繪,為什么其他組件沒有觸發(fā)呢?這就要從頭說起了。

  • 節(jié)流函數(shù)

節(jié)流函數(shù)在初始化的時候產(chǎn)生了一個閉包,閉包內(nèi)保存了變量 last ,這個 last 記錄了上一次執(zhí)行 f 函數(shù)的時間。而當下一次觸發(fā)節(jié)流函數(shù)的時候,如果此時時間 now 減去上次時間 last 小于了我們規(guī)定的節(jié)流時間 wait ,那么函數(shù) f 將不會執(zhí)行。

很顯然,第一個子組件在觸發(fā)節(jié)流函數(shù)的時候產(chǎn)生了一個 last,而第二個組件在觸發(fā)節(jié)流函數(shù)時候的時產(chǎn)生的 now 并沒有滿足 now - last > wait 的條件,所以沒有執(zhí)行重繪代碼。而到了第 n 個組件觸發(fā)節(jié)流函數(shù)的時候,滿足了 now - last > wait 的條件所以重繪成功了。

  • vue 組件

vue 組件在代碼編譯的階段,組件 svgMark 中的方法 reDraw: throttle(function() { this.index++ }, 500) 就已經(jīng)被編譯成了類似如下函數(shù):

reDraw: ƒ (...args) {
 let now = Date.now()
 if (now - last > wait) {
 last = now
 f.apply(this, args)
 }
}

由于函數(shù)是引用類型,所有使用子組件 svgMark 的 methods 中的 reDraw 都指向了同一個內(nèi)存地址,也就是說所有子組件的 reDraw 方法都是同一個函數(shù)。

因為所有組件都公用了同一個節(jié)流函數(shù),當然就會產(chǎn)生節(jié)流了。那怎么解決問題呢?對癥下藥就要讓每個組件產(chǎn)生自己的節(jié)流函數(shù),而不產(chǎn)生共用。代碼如下

子組件:

<template>
 <div>{{ index }}</div>
</template>

<script>
import { throttle } from 'lodash'
export default {
 name: 'SvgMark',
 data() {
 return {
  index: 0
 }
 },
 mounted() {
 this.reDraw = throttle(() => {
  this.index++
 }, 500)
 window.addEventListener('resize', this.reDraw)
 },
 beforeDestroy() {
 window.removeEventListener('resize', this.reDraw)
 }
}
</script>

我們在 mounted 聲明周期函數(shù)中手動聲明了 reDraw 函數(shù)替代 methods 中的 reDraw ,這樣在每個組件初始化的時候都會產(chǎn)生一個自己的節(jié)流函數(shù)了。需要注意此時節(jié)流函數(shù)的參數(shù)使用了箭頭函數(shù),因為這樣 this 才會指向組件實例。

以上就是節(jié)流函數(shù)帶給我的坑,現(xiàn)在分享給大家。[下班][鼓掌]

以上就是vue組件中節(jié)流函數(shù)的失效和解決方法的詳細內(nèi)容,更多關(guān)于vue 組件節(jié)流函數(shù)的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評論

侯马市| 肇源县| 灵川县| 济宁市| 瑞安市| 江源县| 兴城市| 云霄县| 盐边县| 金沙县| 柳江县| 蓝田县| 浦江县| 木兰县| 黄龙县| 芦山县| 滨海县| 巴南区| 慈溪市| 攀枝花市| 鄯善县| 长寿区| 开原市| 宣汉县| 萍乡市| 延安市| 新丰县| 鲜城| 义马市| 卓资县| 兴业县| 北票市| 缙云县| 三明市| 黔西县| 左云县| 泸溪县| 德令哈市| 益阳市| 延津县| 团风县|