| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394 |
- <script setup lang="ts">
- import { TransitionPresets, useTransition } from '@vueuse/core'
- defineOptions({
- name: 'FaCountTo'
- })
- const props = withDefaults(
- defineProps<{
- startVal: number
- endVal: number
- autoplay?: boolean
- duration?: number
- transition?: keyof typeof TransitionPresets
- delay?: number
- decimals?: number
- separator?: string
- prefix?: string
- suffix?: string
- }>(),
- {
- autoplay: true,
- duration: 2000,
- transition: 'linear',
- delay: 0,
- decimals: 0,
- separator: ','
- }
- )
- const emits = defineEmits<{
- onStarted: []
- onFinished: []
- }>()
- const disabled = ref(false)
- const source = ref(props.startVal)
- const outputValue = useTransition(source, {
- duration: props.duration,
- transition: TransitionPresets[props.transition],
- delay: props.delay,
- disabled,
- onStarted: () => emits('onStarted'),
- onFinished: () => emits('onFinished')
- })
- const value = computed(() => {
- let val: number | string = unref(outputValue.value)
- val = Number(val).toFixed(props.decimals)
- if (props.separator) {
- const [integer, decimal] = val.toString().split('.')
- val = integer.replace(/\B(?=(\d{3})+(?!\d))/g, props.separator) + (decimal ? `.${decimal}` : '')
- }
- if (props.prefix) {
- val = props.prefix + val
- }
- if (props.suffix) {
- val = val + props.suffix
- }
- return val
- })
- function start() {
- source.value = props.endVal
- }
- function reset() {
- disabled.value = true
- source.value = props.startVal
- nextTick(() => {
- disabled.value = false
- })
- }
- watch([() => props.startVal, () => props.endVal], () => {
- start()
- })
- onMounted(() => {
- props.autoplay && start()
- })
- defineExpose({
- start,
- reset
- })
- </script>
- <template>
- <span class="flex">
- <span v-if="endVal !== null && endVal !== undefined">{{ value }}</span>
- <slot v-else></slot>
- </span>
- </template>
|