Skip to content

Commit

Permalink
refactor: ♻️ 提供useRaf并重构useCountDown计时逻辑
Browse files Browse the repository at this point in the history
  • Loading branch information
xuqingkai authored and Moonofweisheng committed Aug 9, 2024
1 parent 0e6ea3e commit 661603a
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 52 deletions.
20 changes: 15 additions & 5 deletions src/pages/countDown/Index.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
<!--
* @Author: weisheng
* @Date: 2024-08-09 10:12:54
* @LastEditTime: 2024-08-09 13:10:34
* @LastEditors: weisheng
* @Description:
* @FilePath: \wot-design-uni\src\pages\countDown\Index.vue
* 记得注释
-->
<template>
<page-wraper>
<wd-toast></wd-toast>
<demo-block title="基本用法">
<wd-count-down :time="time" />
</demo-block>
Expand Down Expand Up @@ -33,25 +41,27 @@
<wd-grid-item text="重置" icon="refresh" @itemclick="reset" />
</wd-grid>
</demo-block>
<wd-toast></wd-toast>
</page-wraper>
</template>
<script lang="ts" setup>
import { useToast } from '@/uni_modules/wot-design-uni'
import type { CountDownInstance } from '@/uni_modules/wot-design-uni/components/wd-count-down/types'
import { ref } from 'vue'
const { show: showToast } = useToast()

const time = ref(30 * 60 * 60 * 1000)

const countDown = ref<any>(null)
const countDown = ref<CountDownInstance>()

const start = () => {
countDown.value.start()
countDown.value!.start()
}
const pause = () => {
countDown.value.pause()
countDown.value!.pause()
}
const reset = () => {
countDown.value.reset()
countDown.value!.reset()
}
const onFinish = () => showToast('倒计时结束')
</script>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ref, computed, onBeforeUnmount } from 'vue'
import { isDef } from '../common/util'
import { useRaf } from './useRaf'

// 定义倒计时时间的数据结构
export type CurrentTime = {
Expand Down Expand Up @@ -48,35 +49,20 @@ function isSameSecond(time1: number, time2: number): boolean {
return Math.floor(time1 / 1000) === Math.floor(time2 / 1000)
}

// 判断当前环境是否为 H5
const isH5 = process.env.UNI_PLATFORM === 'h5'

// 封装 requestAnimationFrame 和 setTimeout
function raf(fn: FrameRequestCallback): number {
return isH5 ? requestAnimationFrame(fn) : setTimeout(fn, 33)
}

function cancelRaf(id: number) {
if (isH5) {
cancelAnimationFrame(id)
} else {
clearTimeout(id)
}
}

// 定义 useCountDown 函数
export function useCountDown(options: UseCountDownOptions) {
let timer: number | null = null // 定时器
let endTime: number // 结束时间
let counting: boolean // 是否计时中

const { start: startRaf, cancel: cancelRaf } = useRaf(tick)

const remain = ref(options.time) // 剩余时间
const current = computed(() => parseTime(remain.value)) // 当前倒计时数据

// 暂停倒计时
const pause = () => {
counting = false
cancelRaf(timer!)
cancelRaf()
}

// 获取当前剩余时间
Expand All @@ -86,7 +72,6 @@ export function useCountDown(options: UseCountDownOptions) {
const setRemain = (value: number) => {
remain.value = value
isDef(options.onChange) && options.onChange(current.value)

if (value === 0) {
pause()
isDef(options.onFinish) && options.onFinish()
Expand All @@ -95,36 +80,30 @@ export function useCountDown(options: UseCountDownOptions) {

// 每毫秒更新一次倒计时
const microTick = () => {
timer = raf(() => {
if (counting) {
setRemain(getCurrentRemain())

if (remain.value > 0) {
microTick()
}
if (counting) {
setRemain(getCurrentRemain())
if (remain.value > 0) {
startRaf()
}
})
}
}

// 每秒更新一次倒计时
const macroTick = () => {
timer = raf(() => {
if (counting) {
const remainRemain = getCurrentRemain()

if (!isSameSecond(remainRemain, remain.value) || remainRemain === 0) {
setRemain(remainRemain)
}
if (counting) {
const remainRemain = getCurrentRemain()
if (!isSameSecond(remainRemain, remain.value) || remainRemain === 0) {
setRemain(remainRemain)
}

if (remain.value > 0) {
macroTick()
}
if (remain.value > 0) {
startRaf()
}
})
}
}

// 根据配置项选择更新方式
const tick = () => {
function tick() {
if (options.millisecond) {
microTick()
} else {
Expand All @@ -137,7 +116,7 @@ export function useCountDown(options: UseCountDownOptions) {
if (!counting) {
endTime = Date.now() + remain.value
counting = true
tick()
startRaf()
}
}

Expand Down
37 changes: 37 additions & 0 deletions src/uni_modules/wot-design-uni/components/composables/useRaf.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { ref, onUnmounted } from 'vue'
import { isDef, isH5, isNumber } from '../common/util'

// 定义回调函数类型
type RafCallback = (time: number) => void

export function useRaf(callback: RafCallback) {
const requestRef = ref<number | null | ReturnType<typeof setTimeout>>(null)

// 启动动画帧
const start = () => {
const handle = (time: number) => {
callback(time)
}

if (isH5) {
requestRef.value = requestAnimationFrame(handle)
} else {
requestRef.value = setTimeout(() => handle(Date.now()), 1000 / 30)
}
}

// 取消动画帧
const cancel = () => {
if (isH5 && isNumber(requestRef.value)) {
cancelAnimationFrame(requestRef.value!)
} else if (isDef(requestRef.value)) {
clearTimeout(requestRef.value)
}
}

onUnmounted(() => {
cancel()
})

return { start, cancel }
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,3 @@ export function parseFormat(format: string, timeData: TimeData): string {

return format
}

export function isSameSecond(time1: number, time2: number): boolean {
return Math.floor(time1 / 1000) === Math.floor(time2 / 1000)
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export default {
</script>

<script setup lang="ts">
import { watch, computed } from 'vue'
import { watch, computed, onMounted } from 'vue'
import { parseFormat } from './utils'
import { useCountDown } from '../composables/useCountDown'
import { countDownProps, type CountDownExpose } from './types'
Expand All @@ -37,13 +37,16 @@ const timeText = computed(() => parseFormat(props.format, current.value))
const resetTime = () => {
reset(props.time)
if (props.autoStart) {
start()
}
}
watch(() => props.time, resetTime, { immediate: true })
watch(() => props.time, resetTime, { immediate: false })
onMounted(() => {
resetTime()
})
defineExpose<CountDownExpose>({
start,
Expand Down

0 comments on commit 661603a

Please sign in to comment.