国产成人精品久久免费动漫-国产成人精品天堂-国产成人精品区在线观看-国产成人精品日本-a级毛片无码免费真人-a级毛片毛片免费观看久潮喷

您的位置:首頁技術文章
文章詳情頁

vue組件中節流函數的失效的原因和解決方法

瀏覽:132日期:2022-10-22 10:58:33

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

節流函數

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

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) } }}

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

<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>

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

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

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

節流函數

節流函數在初始化的時候產生了一個閉包,閉包內保存了變量 last ,這個 last 記錄了上一次執行 f 函數的時間。而當下一次觸發節流函數的時候,如果此時時間 now 減去上次時間 last 小于了我們規定的節流時間 wait ,那么函數 f 將不會執行。

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

vue 組件

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

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

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

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

子組件:

<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 聲明周期函數中手動聲明了 reDraw 函數替代 methods 中的 reDraw ,這樣在每個組件初始化的時候都會產生一個自己的節流函數了。需要注意此時節流函數的參數使用了箭頭函數,因為這樣 this 才會指向組件實例。

以上就是節流函數帶給我的坑,現在分享給大家。[下班][鼓掌]

以上就是vue組件中節流函數的失效和解決方法的詳細內容,更多關于vue 組件節流函數的資料請關注好吧啦網其它相關文章!

標簽: Vue
相關文章:
主站蜘蛛池模板: 亚洲精品午夜国产va久久成人 | 我要看欧美精品一级毛片 | 中文一区 | 黄色三级视频在线 | 日韩成人小视频 | 精品成人免费视频 | 中文字幕人成乱码在线观看 | 一级特黄国产高清毛片97看片 | 日本一道免费一区二区三区 | 国内精品不卡一区二区三区 | 国产日韩美国成人 | 亚洲精品国产福利一区二区三区 | 天堂最新版 | 精品国产一区二区三区不卡蜜臂 | 亚洲欧美日韩国产一区二区精品 | 国产精品手机在线亚洲 | 国产精品久久国产三级国不卡顿 | 久草黄视频 | 国产精品自在自线 | 精品国产欧美精品v | 国产91精品高清一区二区三区 | 精品免费久久久久国产一区 | 日韩一区二区三区不卡视频 | 国产禁女女网站免费看 | 国产一区二区三区免费看 | 精品视频一区二区三区四区 | 我要看欧美精品一级毛片 | 欧美视频在线观看免费精品欧美视频 | 91精品国产综合久久久久 | 日本一级做人免费视频 | 精品久久中文字幕有码 | 亚洲精品在线播放视频 | 美国一级毛片片aa久久综合 | 欧美午夜视频一区二区三区 | 毛片大片 | 国产免费成人在线视频 | aa日本| 久久视频精品53在线观看 | 91色综合综合热五月激情 | 免费精品久久久久久中文字幕 | 美女一丝不佳一级毛片香蕉 |