使用Vue封装一个可随时暂停启动无需担心副作用的定时器

 更新时间:2024年11月13日 11:54:18   作者:yulamz  
这篇文章主要为大家详细介绍了如何使用Vue封装一个可随时暂停启动无需担心副作用的定时器,感兴趣的小伙伴可以跟随小编一起学习一下

现成轮子:VueUse 库的 useIntervalFn 方法

是什么?

创建定时器的组合式函数

为什么要用它?

定时执行回调(入参;回调函数、时间间隔、配置项)

控制定时器的行为(返回:开始、暂停定时器的方法)

响应式间隔(入参的时间间隔可以是一个 响应式引用ref 或者一个函数,当它的值改变,定时器会自动更新其间隔时间,无需手动重启定时器)

立即执行选项(入参 options.immediate 控制 是否在初始化时立即启动定时器;入参 options.immediateCallback 控制是否在调用resume方法猴立即执行一次回调函数)

怎么用?

官网有说怎么安装依赖,就不过多解释:https://vueuse.org/shared/useIntervalFn/

分析源码 & 自己手写一个

源码

https://github1s.com/vueuse/vueuse/blob/main/packages/shared/useIntervalFn/index.ts

自己手写

安装vue-demi依赖后,就可以开始手写啦~

import type { ComputedRef, Ref, ShallowRef, WritableComputedRef } from 'vue-demi'
import { getCurrentScope, isRef, onScopeDispose, ref, unref, watch } from 'vue-demi'

/**
 * Void函数
 */
export type Fn = () => void

/**
 * 任意函数
 */
export type AnyFn = (...args: any[]) => any

/**
 * 它可能是一个 ref 对象,或者一个普通的值
 */
export type MaybeRef<T = any> =
| T
| Ref<T>
| ShallowRef<T>
| WritableComputedRef<T>

/**
 * 它可能是一个 ref 对象,或者一个普通的值,或者一个 getter 函数
 * @param cb 
 * @param interval 
 */
export type MaybeRefOrGetter<T = any> = MaybeRef<T> | ComputedRef<T> | (() => T)

/**
 * 获取值、ref 或 getter 的实际值
 */
export function toValue<T>(r: MaybeRefOrGetter<T>): T {
  return typeof r === 'function' ? (r as AnyFn)() : unref(r)
}

/***
 * 是否为客户端
 */
export const isClient = typeof window !== 'undefined' && typeof document !== 'undefined'

/**
 * 是否处于一个 Vue 3 的响应式 effect 生命周期的作用域内。如果是的话,它会注册一个清理函数(fn 参数),该函数会在作用域结束时执行;如果不是在这样的作用域内,那么它将不做任何操作。
 * @param fn 
 */
export function tryOnScopeDispose(fn: Fn) {
  if (getCurrentScope()) {
    onScopeDispose(fn)
    return true
  }
  return false
}


export interface UseIntervalOptions {
  /**
   * 立即执行这个定时器
   */
  immediate?: boolean
  /**
   * 在调用 resume 函数后,立即执行回调函数
   */
  immediateCallback?: boolean
}

export interface Pausable {
  /**
   * 一个 ref 表示 pausable 实例是否处于活动状态
   */
  isActive: Readonly<Ref<boolean>>
  /**
   * 暂停定时器
   */
  pause: Fn
  /**
   * 恢复定时器
   */
  resume: Fn
}

export function useIntervalFn(cb: Fn, interval: MaybeRefOrGetter<number> = 1000, options: UseIntervalOptions = {}): Pausable {
  const {
    immediate = true,
    immediateCallback = true
  } = options

  let timer: ReturnType<typeof setInterval> | null = null
  const isActive = ref(false)

  function clean() {
    if (timer) {
      clearInterval(timer)
      timer = null
    }
  }

  function pause() {
    isActive.value = false
    clean()
  }

  function resume() {
    const intervalValue = toValue(interval)
    if (intervalValue <= 0) {
      return
    }
    isActive.value = true

    if (immediateCallback){
      cb()
    }

    clean()

    if (isActive.value) {
      timer = setInterval(cb, intervalValue)
    }
  }

  
  if (immediate && isClient) {
    resume()
  }

  if (isRef(interval) || typeof interval === 'function') {
    const stopWatch = watch(interval, () => {
      if (isActive.value && isClient) {
        resume()
      }
    })
    tryOnScopeDispose(stopWatch)
  }

  tryOnScopeDispose(pause)

  return {
    isActive,
    pause,
    resume
  }
}

到此这篇关于使用Vue封装一个可随时暂停启动无需担心副作用的定时器的文章就介绍到这了,更多相关Vue封装定时器内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • vue自定义指令添加跟随鼠标光标提示框v-tooltip方式

    vue自定义指令添加跟随鼠标光标提示框v-tooltip方式

    这篇文章主要介绍了vue自定义指令添加跟随鼠标光标提示框v-tooltip方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-10-10
  • Vue之Axios异步通信详解

    Vue之Axios异步通信详解

    这篇文章主要为大家介绍了Vue之Axios异步通信,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2021-11-11
  • Vue.js之$emit用法案例详解

    Vue.js之$emit用法案例详解

    这篇文章主要介绍了Vue.js之$emit用法案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-09-09
  • vue使用driver.js完成页面引导功能的示例详解

    vue使用driver.js完成页面引导功能的示例详解

    在Vue中,driver.js通常是指用于实现用户引导和教程功能的JavaScript库,它可以帮助开发者在应用程序中创建交互式的引导和教程,以引导用户了解应用程序的不同功能和界面,本文就简单的给大家介绍一下vue如何使用driver.js完成页面引导功能
    2023-08-08
  • 详解vue2与vue3获取模版引用ref的区别

    详解vue2与vue3获取模版引用ref的区别

    这篇文章主要为大家详细介绍了vue2与vue3中获取模版引用ref的方法与区别,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2023-10-10
  • Vue 3 中 toRaw 的用法详细讲解

    Vue 3 中 toRaw 的用法详细讲解

    `toRaw` 是 Vue3 提供的一个 API,用于获取响应式对象的原始非响应式对象,主要用于调试、与第三方库兼容以及避免无限递归更新等场景,使用时需要注意不要滥用,以免破坏响应式系统,感兴趣的朋友跟随小编一起看看吧
    2024-11-11
  • 详解Vue与VueComponent的关系

    详解Vue与VueComponent的关系

    这篇文章主要为大家介绍了Vue与VueComponent的关系,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2021-12-12
  • Vue+Websocket简单实现聊天功能

    Vue+Websocket简单实现聊天功能

    这篇文章主要为大家详细介绍了Vue+Websocket简单实现聊天功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-08-08
  • 基于Vue实现一个textarea幽灵建议功能

    基于Vue实现一个textarea幽灵建议功能

    不知道你有没有发现Bing AI聊天有个输入提示功能,在用户输入部分内容时后面会给出灰色提示文案,用户只要按下tab键就可以快速添加提示的后续内容,我将这个功能称为幽灵建议,接下来我将用Vue框架来实现这个功能,需要的朋友可以参考下
    2023-09-09
  • vue2笔记 — vue-router路由懒加载的实现

    vue2笔记 — vue-router路由懒加载的实现

    本篇文章主要介绍了vue2笔记 — vue-router路由懒加载示例,实例分析了vue-router路由懒加载的实现,具有一定参考借鉴价值,需要的朋友可以参考下
    2017-03-03

最新评论