wd-count-down.vue 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. <template>
  2. <view :class="`wd-count-down ${customClass}`" :style="customStyle">
  3. <slot :current="current" v-if="$slots.default" />
  4. <block v-else>{{ timeText }}</block>
  5. </view>
  6. </template>
  7. <script lang="ts">
  8. export default {
  9. name: 'wd-count-down',
  10. options: {
  11. virtualHost: true,
  12. addGlobalClass: true,
  13. styleIsolation: 'shared'
  14. }
  15. }
  16. </script>
  17. <script setup lang="ts">
  18. import { watch, computed, onMounted } from 'vue'
  19. import { parseFormat } from './utils'
  20. import { useCountDown } from '../composables/useCountDown'
  21. import { countDownProps, type CountDownExpose } from './types'
  22. const props = defineProps(countDownProps)
  23. const emit = defineEmits(['change', 'finish'])
  24. const { start, pause, reset, current } = useCountDown({
  25. time: props.time,
  26. millisecond: props.millisecond,
  27. onChange: (current) => emit('change', current),
  28. onFinish: () => emit('finish')
  29. })
  30. const timeText = computed(() => parseFormat(props.format, current.value))
  31. const resetTime = () => {
  32. reset(props.time)
  33. if (props.autoStart) {
  34. start()
  35. }
  36. }
  37. watch(() => props.time, resetTime, { immediate: false })
  38. onMounted(() => {
  39. resetTime()
  40. })
  41. defineExpose<CountDownExpose>({
  42. start,
  43. pause,
  44. reset: resetTime
  45. })
  46. </script>
  47. <style lang="scss" scoped>
  48. @import './index.scss';
  49. </style>