Skip to content

Commit

Permalink
feat: useCountdown
Browse files Browse the repository at this point in the history
  • Loading branch information
nemo-shen committed Feb 11, 2024
1 parent fa27d89 commit 9974173
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 22 deletions.
1 change: 1 addition & 0 deletions .eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ module.exports = {
},
plugins: ['vue', '@typescript-eslint', 'markdown'],
rules: {
'no-console': ['error', { allow: ['warn', 'error'] }],
'import/prefer-default-export': 'off',
'@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
'import/no-extraneous-dependencies': [
Expand Down
1 change: 1 addition & 0 deletions packages/core/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ export * from './useEllipsis'
export * from './useLoading'
export * from './useProgress'
export * from './useCalendar'
export * from './useCountdown'
91 changes: 70 additions & 21 deletions packages/core/useCountdown/index.ts
Original file line number Diff line number Diff line change
@@ -1,51 +1,100 @@
import { ref, type Ref } from 'vue'
import { ref, type Ref, watch, computed } from 'vue'

interface UseCountdownOptions {
duration: number
interval?: number
immediate?: boolean
onComplete: () => {}
onComplete?: () => void
}

interface Countdown {
readonly value: number // 总时间
format: 'HH:mm:ss'
setValue: () => {}
getYears: () => {}
getMonths: () => {}
getDays: () => {}
getMinutes: () => {}
getHours: () => {}
getSeconds: () => {}
getMilliseconds: () => {}
total: number
days: number
hours: number
minutes: number
seconds: number
milliseconds: number
}

interface UseCountdownReturn {
countdown: Ref<Countdown>
start: () => void // 开始
pause: () => void // 暂停
stop: () => void // 暂停
reset: () => void // 重置
isRunning: Ref<boolean> // 是否在运行
}

export const useCountdown = (
options?: UseCountdownOptions
options: UseCountdownOptions
): UseCountdownReturn => {
const { duration, interval = 1000, immediate = false, onComplete } = options
console.log(duration, interval, immediate, onComplete)
const countdown = ref<Countdown>()
const remainingTime = ref(duration)
const isRunning = ref(false)
let timer: number

const start = () => {}
const pause = () => {}
const reset = () => {}
const clearTimer = () => {
if (timer) {
clearInterval(timer)
}
}

const start = () => {
if (isRunning.value) {
console.warn('Countdown has already running')
return
}
isRunning.value = true
timer = setInterval(() => {
const time = remainingTime.value - interval;
remainingTime.value = time >= 0 ? time : 0
}, interval) as unknown as number
}
const stop = () => {
isRunning.value = false
clearTimer()
}
const reset = () => {
if (immediate) {
remainingTime.value = duration
} else {
clearTimer()
isRunning.value = false
remainingTime.value = duration
}
}

if (immediate) {
start()
}

const countdown = computed(() => {
const milliseconds = remainingTime.value
const seconds = Math.floor(milliseconds / 1000)
const minutes = Math.floor(milliseconds / 1000 / 60)
const hours = Math.floor(milliseconds / 1000 / 60 / 60)
const days = Math.floor(milliseconds / 1000 / 60 / 60 / 24)
return {
total: milliseconds,
days,
hours: hours % 24,
minutes: minutes % 60,
seconds: seconds % 60,
milliseconds: milliseconds % 1000,
}
})

const isRunning = ref(false);
watch(remainingTime, (value) => {
if (value === 0) {
if (timer) clearInterval(timer)
onComplete()
}
})

return {
countdown,
isRunning,
start,
pause,
stop,
reset,
}
}
4 changes: 3 additions & 1 deletion src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
// import UseLoading from './demo/UseLoading.vue'
// import UseProgress from './demo/UseProgress.vue'
import UseCalendar from './demo/UseCalendar.vue'
import UseCountdown from './demo/UseCountdown.vue'
</script>

<template>
<!-- <UseEllipsis /> -->
<!-- <UseLoading /> -->
<!-- <UseProgress /> -->
<UseCalendar />
<!-- <UseCalendar /> -->
<UseCountdown />
</template>
22 changes: 22 additions & 0 deletions src/demo/UseCountdown.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<script setup lang="ts">
import { watch, ref, h, VNode } from 'vue'
import { useCountdown } from '@noi/core'
const { countdown, start, stop, reset } = useCountdown({
duration: 3000,
interval: 100,
onComplete: () => {
console.log('complete');
}
})
</script>

<template>
{{ countdown }}
<br />
<button @click="start">start</button>
<br />
<button @click="stop">stop</button>
<br />
<button @click="reset">reset</button>
</template>

0 comments on commit 9974173

Please sign in to comment.