欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

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

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

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

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è)有一個(gè) vue 組件 svgMark。這個(gè)組件中渲染的元素要在頁(yè)面窗口大小發(fā)生變化時(shí)重繪 reDraw ,而重繪時(shí)要使用節(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>

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

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

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

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

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

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

  • vue 組件

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

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

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

因?yàn)樗薪M件都公用了同一個(gè)節(jié)流函數(shù),當(dāng)然就會(huì)產(chǎn)生節(jié)流了。那怎么解決問(wèn)題呢?對(duì)癥下藥就要讓每個(gè)組件產(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>

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

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

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

相關(guān)文章

  • vue實(shí)現(xiàn)登錄頁(yè)背景粒子特效

    vue實(shí)現(xiàn)登錄頁(yè)背景粒子特效

    這篇文章主要為大家詳細(xì)介紹了vue實(shí)現(xiàn)登錄頁(yè)背景粒子特效,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-04-04
  • 前端vue+element使用SM4國(guó)密加密解密的詳細(xì)實(shí)例

    前端vue+element使用SM4國(guó)密加密解密的詳細(xì)實(shí)例

    國(guó)密即國(guó)家密碼局認(rèn)定的國(guó)產(chǎn)密碼算法,主要有SM1,SM2,SM3,SM4,下面這篇文章主要給大家介紹了關(guān)于前端vue+element使用SM4國(guó)密加密解密的相關(guān)資料,需要的朋友可以參考下
    2023-03-03
  • 詳解Vue依賴(lài)收集引發(fā)的問(wèn)題

    詳解Vue依賴(lài)收集引發(fā)的問(wèn)題

    這篇文章主要介紹了Vue依賴(lài)收集引發(fā)的問(wèn)題,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • vue-cli 目錄結(jié)構(gòu)詳細(xì)講解總結(jié)

    vue-cli 目錄結(jié)構(gòu)詳細(xì)講解總結(jié)

    這篇文章主要介紹了vue-cli 目錄結(jié)構(gòu)詳細(xì)講解總結(jié),詳細(xì)的介紹了整個(gè)項(xiàng)目的目錄以及目錄文件的用法,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2019-01-01
  • webpack+vue.js實(shí)現(xiàn)組件化詳解

    webpack+vue.js實(shí)現(xiàn)組件化詳解

    vue的開(kāi)發(fā)體驗(yàn)還是比較愉悅的。首先文檔非常友好,所以上手會(huì)比較快。其次,配合webpack和vue-loader,每個(gè)頁(yè)面都是一個(gè).vue文件,寫(xiě)起來(lái)很方便。所以很適合做組件化開(kāi)發(fā),這篇文章我們就來(lái)一起看看webpack+vue.js如何實(shí)現(xiàn)組件化。
    2016-10-10
  • Vue單頁(yè)面應(yīng)用保證F5強(qiáng)刷不清空數(shù)據(jù)的解決方案

    Vue單頁(yè)面應(yīng)用保證F5強(qiáng)刷不清空數(shù)據(jù)的解決方案

    最近小編遇到這樣的問(wèn)題當(dāng)vue單頁(yè)面按F5強(qiáng)刷,數(shù)據(jù)就恢復(fù)初始了,這怎么辦呢?下面小編給大家?guī)?lái)了Vue單頁(yè)面應(yīng)用保證F5強(qiáng)刷不清空數(shù)據(jù)的解決方案,感興趣的朋友一起看看吧
    2018-01-01
  • vue3使用axios并封裝axios請(qǐng)求的詳細(xì)步驟

    vue3使用axios并封裝axios請(qǐng)求的詳細(xì)步驟

    本篇文章分步驟給大家介紹了vue3使用axios并封裝axios請(qǐng)求的詳細(xì)步驟,結(jié)合實(shí)例代碼給大家講解的非常詳細(xì),需要的朋友參考下吧
    2023-06-06
  • Vue中前端與后端如何實(shí)現(xiàn)交互

    Vue中前端與后端如何實(shí)現(xiàn)交互

    這篇文章主要介紹了Vue中前端與后端如何實(shí)現(xiàn)交互,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-09-09
  • 詳解Vue slot插槽

    詳解Vue slot插槽

    這篇文章主要為大家介紹了Vue的slot插槽,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2021-11-11
  • 在vue中動(dòng)態(tài)修改css其中一個(gè)屬性值操作

    在vue中動(dòng)態(tài)修改css其中一個(gè)屬性值操作

    這篇文章主要介紹了在vue中動(dòng)態(tài)修改css其中一個(gè)屬性值操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-12-12

最新評(píng)論