插件窝 干货文章 Vue页面卸载时如何优雅地停止定时器?

Vue页面卸载时如何优雅地停止定时器?

定时器 timer 组件 使用 685    来源:    2025-03-26

Vue 中优雅地停止定时器

在 Vue 组件中使用定时器时,确保在组件卸载时正确清理定时器是非常重要的,否则可能会导致内存泄漏和意外的行为。以下是几种优雅地停止定时器的方法:

1. 使用 beforeDestroybeforeUnmount 生命周期钩子

export default {
  data() {
    return {
      timer: null
    }
  },
  mounted() {
    this.timer = setInterval(() => {
      // 定时器逻辑
    }, 1000)
  },
  beforeDestroy() { // Vue 2
    clearInterval(this.timer)
  },
  beforeUnmount() { // Vue 3
    clearInterval(this.timer)
  }
}

2. 使用 onBeforeUnmount 组合式 API (Vue 3)

import { onBeforeUnmount, ref } from 'vue'

export default {
  setup() {
    const timer = ref(null)

    timer.value = setInterval(() => {
      // 定时器逻辑
    }, 1000)

    onBeforeUnmount(() => {
      clearInterval(timer.value)
    })

    return { timer }
  }
}

3. 使用 watchEffect 自动清理 (Vue 3)

import { watchEffect } from 'vue'

export default {
  setup() {
    watchEffect((onCleanup) => {
      const timer = setInterval(() => {
        // 定时器逻辑
      }, 1000)

      // 自动清理函数
      onCleanup(() => {
        clearInterval(timer)
      })
    })
  }
}

4. 使用可清除的定时器封装

// utils/timer.js
export function useInterval(callback, delay) {
  const timer = ref(null)

  const start = () => {
    timer.value = setInterval(callback, delay)
  }

  const stop = () => {
    if (timer.value) {
      clearInterval(timer.value)
      timer.value = null
    }
  }

  onBeforeUnmount(stop)

  return { start, stop }
}

// 组件中使用
import { useInterval } from '@/utils/timer'

export default {
  setup() {
    const { start, stop } = useInterval(() => {
      // 定时器逻辑
    }, 1000)

    start()

    return { stop }
  }
}

最佳实践建议

  1. 始终清理定时器:确保在组件卸载时清理所有定时器
  2. 使用组件数据存储定时器引用:避免使用全局变量存储定时器
  3. 考虑使用第三方库:如 vue-use 中的 useInterval 等工具
  4. 处理暂停场景:如果组件可能被暂停而非销毁,考虑实现暂停/恢复功能

通过以上方法,可以确保 Vue 组件中的定时器在组件卸载时被正确清理,避免内存泄漏和意外行为。