Skip to content

Commit

Permalink
refactor(countdown): move to script setup (#3018)
Browse files Browse the repository at this point in the history
  • Loading branch information
subordon authored Apr 16, 2024
1 parent 315c17d commit 48c7220
Show file tree
Hide file tree
Showing 11 changed files with 478 additions and 568 deletions.
1 change: 1 addition & 0 deletions src/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -703,6 +703,7 @@
{
"name": "Countdown",
"cName": "倒计时",
"setup": true,
"desc": "倒计时",
"author": "yangxiaolu"
},
Expand Down
176 changes: 176 additions & 0 deletions src/packages/__VUE/countdown/countdown.taro.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
<template>
<view class="nut-countdown">
<slot>
<view class="nut-countdown__content" v-html="renderTime"></view>
</slot>
</view>
</template>

<script setup lang="ts">
import { ref, computed, watch, onBeforeMount } from 'vue'
import { getTimeStamp, formatRemainTime } from './util'
defineOptions({
name: 'NutCountdown'
})
export type CountdownProps = Partial<{
modelValue: Record<string, string>
paused: boolean
startTime: number | string
endTime: number | string
millisecond: boolean
format: string
autoStart: boolean
time: number | string
}>
const props = withDefaults(defineProps<CountdownProps>(), {
paused: false,
startTime: '',
endTime: '',
millisecond: false,
format: 'HH:mm:ss',
autoStart: true,
time: 0
})
const emit = defineEmits([
'input',
'update:modelValue',
'end',
'restart',
'paused',
// will be deprecated
'onEnd',
'onRestart',
'onPaused'
])
// 倒计时剩余时间时间
const restTime = ref(0)
const timer = ref<null | number>(null)
const counting = ref(!props.paused && props.autoStart)
const handleEndTime = ref(Date.now())
// 设置了 startTime 时,与 date.now() 的差异
const diffTime = ref(0)
const renderTime = computed(() => {
return formatRemainTime(restTime.value, props.format)
})
// 倒计时 interval
const initTime = () => {
handleEndTime.value = Number(props.endTime)
diffTime.value = Date.now() - getTimeStamp(props.startTime) // 时间差
if (!counting.value) counting.value = true
tick()
}
const tick = () => {
if (window !== undefined) {
timer.value = requestAnimationFrame(() => {
if (counting.value) {
const currentTime = Date.now() - diffTime.value
const remainTime = Math.max(handleEndTime.value - currentTime, 0)
restTime.value = remainTime
if (!remainTime) {
counting.value = false
pause()
emit('end')
emit('onEnd')
}
if (remainTime > 0) {
tick()
}
}
})
}
}
// 开始
const start = () => {
if (!counting.value && !props.autoStart) {
counting.value = true
handleEndTime.value = Date.now() + Number(restTime.value)
tick()
emit('restart', restTime.value)
emit('onRestart', restTime.value)
}
}
// 暂定
const pause = () => {
cancelAnimationFrame(timer.value!)
counting.value = false
emit('restart', restTime.value)
emit('onRestart', restTime.value)
}
// 重置
const reset = () => {
if (!props.autoStart) {
pause()
restTime.value = Number(props.time)
}
}
defineExpose({
start,
pause,
reset
})
onBeforeMount(() => {
if (props.autoStart) {
initTime()
} else {
restTime.value = Number(props.time)
}
})
watch(
() => restTime.value,
(value) => {
const tranTime = formatRemainTime(value, props.format, 'custom')
emit('update:modelValue', tranTime)
emit('input', tranTime)
}
)
watch(
() => props.paused,
(v, ov) => {
if (!ov) {
if (counting.value) {
pause()
}
} else {
if (!counting.value) {
counting.value = true
handleEndTime.value = Date.now() + Number(restTime.value)
tick()
}
emit('restart', restTime.value)
emit('onRestart', restTime.value)
}
}
)
watch(
() => props.endTime,
() => {
initTime()
}
)
watch(
() => props.startTime,
() => {
initTime()
}
)
</script>
176 changes: 176 additions & 0 deletions src/packages/__VUE/countdown/countdown.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
<template>
<view class="nut-countdown">
<slot>
<view class="nut-countdown__content" v-html="renderTime"></view>
</slot>
</view>
</template>

<script setup lang="ts">
import { ref, computed, watch, onBeforeMount } from 'vue'
import { getTimeStamp, formatRemainTime } from './util'
defineOptions({
name: 'NutCountdown'
})
export type CountdownProps = Partial<{
modelValue: Record<string, string>
paused: boolean
startTime: number | string
endTime: number | string
millisecond: boolean
format: string
autoStart: boolean
time: number | string
}>
const props = withDefaults(defineProps<CountdownProps>(), {
paused: false,
startTime: '',
endTime: '',
millisecond: false,
format: 'HH:mm:ss',
autoStart: true,
time: 0
})
const emit = defineEmits([
'input',
'update:modelValue',
'end',
'restart',
'paused',
// will be deprecated
'onEnd',
'onRestart',
'onPaused'
])
// 倒计时剩余时间时间
const restTime = ref(0)
const timer = ref<null | number>(null)
const counting = ref(!props.paused && props.autoStart)
const handleEndTime = ref(Date.now())
// 设置了 startTime 时,与 date.now() 的差异
const diffTime = ref(0)
const renderTime = computed(() => {
return formatRemainTime(restTime.value, props.format)
})
// 倒计时 interval
const initTime = () => {
handleEndTime.value = Number(props.endTime)
diffTime.value = Date.now() - getTimeStamp(props.startTime) // 时间差
if (!counting.value) counting.value = true
tick()
}
const tick = () => {
if (window !== undefined) {
timer.value = requestAnimationFrame(() => {
if (counting.value) {
const currentTime = Date.now() - diffTime.value
const remainTime = Math.max(handleEndTime.value - currentTime, 0)
restTime.value = remainTime
if (!remainTime) {
counting.value = false
pause()
emit('end')
emit('onEnd')
}
if (remainTime > 0) {
tick()
}
}
})
}
}
// 开始
const start = () => {
if (!counting.value && !props.autoStart) {
counting.value = true
handleEndTime.value = Date.now() + Number(restTime.value)
tick()
emit('restart', restTime.value)
emit('onRestart', restTime.value)
}
}
// 暂定
const pause = () => {
cancelAnimationFrame(timer.value!)
counting.value = false
emit('restart', restTime.value)
emit('onRestart', restTime.value)
}
// 重置
const reset = () => {
if (!props.autoStart) {
pause()
restTime.value = Number(props.time)
}
}
defineExpose({
start,
pause,
reset
})
onBeforeMount(() => {
if (props.autoStart) {
initTime()
} else {
restTime.value = Number(props.time)
}
})
watch(
() => restTime.value,
(value) => {
const tranTime = formatRemainTime(value, props.format, 'custom')
emit('update:modelValue', tranTime)
emit('input', tranTime)
}
)
watch(
() => props.paused,
(v, ov) => {
if (!ov) {
if (counting.value) {
pause()
}
} else {
if (!counting.value) {
counting.value = true
handleEndTime.value = Date.now() + Number(restTime.value)
tick()
}
emit('restart', restTime.value)
emit('onRestart', restTime.value)
}
}
)
watch(
() => props.endTime,
() => {
initTime()
}
)
watch(
() => props.startTime,
() => {
initTime()
}
)
</script>
11 changes: 11 additions & 0 deletions src/packages/__VUE/countdown/doc.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,17 @@ Paused and restarted the countdown with the `paused` attribute
| pause | Count Down Pause |
| reset | Count Down Reset |

### Types version

The component exports the following type definitions:

```js
import type {
CountdownProps,
CountdownInstance
} from '@nutui/nutui'
```

## Theming

### CSS Variables
Expand Down
11 changes: 11 additions & 0 deletions src/packages/__VUE/countdown/doc.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,17 @@ app.use(Countdown)
| pause | 暂停倒计时 |
| reset | 重设倒计时,若 `auto-start``true`,重设后会自动开始倒计时 |

### 类型定义 version

组件导出以下类型定义:

```js
import type {
CountdownProps,
CountdownInstance
} from '@nutui/nutui'
```

## 主题定制

### 样式变量
Expand Down
Loading

0 comments on commit 48c7220

Please sign in to comment.