成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Vue3 的 watch,性能真的很差!你們知道怎么優化嗎?

開發 前端
如果頁面中使用了大量的 watch ,但是又沒有進行防抖或者節流的限制,就會導致頁面非常卡頓。

最近發現公司某個 Vue 頁面非常卡,一看原來是因為頁面中使用了大量的 watch ,但是又沒有進行防抖或者節流的限制,導致了觸發非常頻繁,所以頁面非常卡頓。

所以想著,想分享一下如何給 watch 加上 防抖、節流。

一、前置知識:防抖與節流

在實現監聽器之前,我們需要理解兩個核心概念:

  • 防抖(Debounce): 在連續觸發時,只在最后一次操作后等待指定時間執行
  • 節流(Throttle): 在連續觸發時,保證固定時間間隔內只執行一次

二、基礎監聽器實現

我們先實現一個簡單的響應式監聽器,基于Vue的watch函數:

/**
 * 基礎監聽器
 * @param {Ref} source 要監聽的響應式數據
 * @param {Function} callback 變化回調
 * @param {Object} options 監聽選項
 */
function basicWatcher(source, callback, options = {}) {
let cleanup = () => {}

const stop = watch(source, (value, oldValue, onCleanup) => {
    // 清除之前的副作用
    cleanup()
    
    // 注冊新的清理函數
    onCleanup(() => {
      cleanup = () => {}
    })
    
    // 執行回調
    callback(value, oldValue)
  }, options)

return stop
}

三、實現防抖監聽器(watchDebounced)

實現要點:

  • 使用 setTimeout 延遲回調執行
  • 每次新變化時重置定時器
  • 清理函數確保組件卸載時終止等待中的回調
/**
 * 防抖監聽器
 * @param {Ref} source 要監聽的響應式數據
 * @param {Function} callback 回調函數
 * @param {number} delay 防抖延遲時間(毫秒)
 * @param {Object} options 監聽選項
 */
function watchDebounced(source, callback, delay = 300, options = {}) {
let timeoutId = null
let cleanup = () => {}

const stop = watch(source, (value, oldValue, onCleanup) => {
    // 清除之前的定時器和副作用
    clearTimeout(timeoutId)
    cleanup()

    // 設置新的定時器
    timeoutId = setTimeout(() => {
      // 執行回調時綁定正確的this上下文
      callback.call(this, value, oldValue)
    }, delay)

    // 注冊清理函數
    onCleanup(() => {
      clearTimeout(timeoutId)
      cleanup = () => {}
    })
  }, options)

return stop
}

四、實現節流監聽器(watchThrottled)

實現要點:

  • 使用時間戳計算剩余可執行時間
  • 未到間隔時間時,設置剩余時間的定時器
  • 保證間隔時間內至少執行一次
/**
 * 節流監聽器
 * @param {Ref} source 要監聽的響應式數據
 * @param {Function} callback 回調函數
 * @param {number} interval 節流間隔(毫秒)
 * @param {Object} options 監聽選項
 */
function watchThrottled(source, callback, interval = 300, options = {}) {
let lastExecTime = 0
let cleanup = () => {}
let timeoutId = null

const stop = watch(source, (value, oldValue, onCleanup) => {
    const now = Date.now()
    const elapsed = now - lastExecTime

    // 清除等待中的定時器
    clearTimeout(timeoutId)
    cleanup()

    if (elapsed >= interval) {
      // 立即執行
      callback(value, oldValue)
      lastExecTime = now
    } else {
      // 設置剩余時間的定時器
      timeoutId = setTimeout(() => {
        callback(value, oldValue)
        lastExecTime = Date.now()
      }, interval - elapsed)
    }

    onCleanup(() => {
      clearTimeout(timeoutId)
      cleanup = () => {}
    })
  }, options)

return stop
}

五、使用示例

<script setup>
import { ref } from 'vue'

const searchKeyword = ref('')

// 防抖監聽示例
watchDebounced(
  searchKeyword,
  (newVal) => {
    console.log('防抖搜索:', newVal)
    // 這里可以執行API請求
  },
  500
)

// 節流監聽示例
watchThrottled(
  searchKeyword,
  (newVal) => {
    console.log('節流記錄:', newVal)
    // 這里可以執行高頻狀態記錄
  },
  1000
)
</script>
責任編輯:趙寧寧 來源: 前端之神
相關推薦

2025-04-07 08:50:36

2010-01-21 17:14:40

C++兼容

2013-03-20 18:14:35

架構架構設計項目

2024-07-15 08:02:37

2024-09-05 08:50:11

2020-11-12 08:32:14

Vue3模板優化

2022-07-14 08:22:48

Computedvue3

2016-04-21 09:43:33

編程音樂

2010-02-23 16:21:24

Python Win

2010-03-02 17:22:46

Android技術

2022-06-09 08:28:27

Vue3watchwatchEffec

2023-12-14 08:25:14

WatchVue.js監聽數據

2016-11-15 09:43:56

大數據數據工程師

2020-08-07 16:18:38

JavaScriptC++Python

2025-03-10 08:48:14

Vue生態編程

2010-03-02 15:22:40

Android手機

2022-06-21 12:09:18

Vue差異

2021-08-26 21:55:38

DPU架構數據

2010-01-20 10:14:53

C++程序

2021-08-31 10:52:30

容量背包物品
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美亚洲一级 | 综合伊人 | 在线观看视频你懂得 | 99re免费 | 中文字幕一区二区三区精彩视频 | 日韩在线中文字幕 | 国产精品无码专区在线观看 | 欧美久久视频 | 国产乱码精品一区二区三区五月婷 | 日韩在线三级 | 久久大全 | 99久久精品国产毛片 | 成人一区二区三区在线观看 | 国产麻豆乱码精品一区二区三区 | 中文字幕综合 | 五月婷婷丁香婷婷 | 国产剧情一区 | 成人国产精品入口免费视频 | 在线免费中文字幕 | 久久久久久91 | 日本欧美黄色片 | 精品国产一区探花在线观看 | 成人精品一区 | 国产精品乱码一区二三区小蝌蚪 | 午夜看电影在线观看 | 亚洲精品乱码久久久久久久久 | 久久亚洲一区二区三 | 天天操夜夜操 | 精品福利av导航 | 亚洲精品免费观看 | 久久久久久久一区二区 | 久久久久国产一级毛片 | 国产高清视频在线 | 夜夜干夜夜操 | 91精品国产综合久久久久久丝袜 | 国户精品久久久久久久久久久不卡 | 国产人成精品一区二区三 | 欧美日日 | 国产在线一区二区三区 | 欧美性受xxxx | 欧美精品v |