APIs
参数 | 说明 | 类型 | 默认值 | 必传 |
---|
from | 数值动画起始数值 | number | 0 | false |
to | 数值目标值 | number | 1000 | false |
duration | 数值动画持续时间,单位ms | number | 3000 | false |
autoplay | 是否自动开始动画 | boolean | true | false |
precision | 精度,保留小数点后几位 | number | 0 | false |
prefix | 前缀 | string | ‘’ | false |
suffix | 后缀 | string | ‘’ | false |
separator | 千分位分隔符 | string | ‘,’ | false |
decimal | 小数点字符 | string | ‘.’ | false |
color | 数值文本颜色 | string | undefined | false |
transition | 动画过渡效果 | TransitionFunc | TransitionFunc[‘easeInOutCubic’] | false |
Events
事件名称 | 说明 | 参数 |
---|
play | 播放动画 | () => void |
started | 动画开始播放 | () => void |
finished | 动画播放完成 | () => void |
创建数值动画组件NumberAnimation.vue
<script setup lang="ts">
import { ref, computed, watchEffect, onMounted, watch } from 'vue'
import { useTransition, TransitionPresets } from '@vueuse/core'
enum TransitionFunc {linear = 'linear',easeOutSine = 'easeOutSine',easeInOutSine = 'easeInOutSine',easeInQuad = 'easeInQuad',easeOutQuad = 'easeOutQuad',easeInOutQuad = 'easeInOutQuad',easeInCubic = 'easeInCubic',easeOutCubic = 'easeOutCubic',easeInOutCubic = 'easeInOutCubic',easeInQuart = 'easeInQuart',easeOutQuart = 'easeOutQuart',easeInOutQuart = 'easeInOutQuart',easeInQuint = 'easeInQuint',easeOutQuint = 'easeOutQuint',easeInOutQuint = 'easeInOutQuint',easeInExpo = 'easeInExpo',easeOutExpo = 'easeOutExpo',easeInOutExpo = 'easeInOutExpo',easeInCirc = 'easeInCirc',easeOutCirc = 'easeOutCirc',easeInOutCirc = 'easeInOutCirc',easeInBack = 'easeInBack',easeOutBack = 'easeOutBack',easeInOutBack = 'easeInOutBack'
}
interface Props {from?: number to?: number duration?: number autoplay?: boolean precision?: number prefix?: string suffix?: string separator?: string decimal?: string color?: string transition?: TransitionFunc
}
const props = withDefaults(defineProps<Props>(), {from: 0,to: 1000,duration: 3000,autoplay: true,precision: 0,prefix: '',suffix: '',separator: ',',decimal: '.',color: undefined,transition: TransitionFunc['easeInOutCubic']
})
const source = ref(props.from)
watchEffect(() => {source.value = props.from
})
watch([() => props.from, () => props.to],() => {if (props.autoplay) {play()}}
)
onMounted(() => {props.autoplay && play()
})
const outputValue = useTransition(source, {duration: props.duration,transition: TransitionPresets[props.transition],onFinished: () => emits('finished'),onStarted: () => emits('started')})
function play () {source.value = props.to
}
const showValue = computed(() => formatNumber(outputValue.value))
function isNumber (val: any) {return Object.prototype.toString.call(val) === '[object Number]'
}
const emits = defineEmits(['started', 'finished'])
function formatNumber (num: number | string) {const { precision, decimal, separator, suffix, prefix } = propsif (num === 0) {return num.toFixed(precision)}if (!num) {return ''}num = Number(num).toFixed(precision)num += ''const x = num.split('.')let x1 = x[0]const x2 = x.length > 1 ? decimal + x[1] : ''const rgx = /(\d+)(\d{3})/if (separator && !isNumber(separator)) {while (rgx.test(x1)) {x1 = x1.replace(rgx, '$1' + separator + '$2')}}return prefix + x1 + x2 + suffix
}
defineExpose({play
})
</script>
<template><span :style="{ color }">{{ showValue }}</span>
</template>
在要使用的页面引入
<script setup lang="ts">
import NumberAnimation from 'NumberAnimation.vue'
import { ref } from 'vue'function onStarted () {console.log('started')
}
function onFinished () {console.log('finished')
}
const animationRef = ref()
function onClick () {animationRef.value.play()
}
</script>
<template><div><h1>NumberAnimation 数值动画</h1><h2 class="mt30 mb10">基本使用</h2><Row><Col :span="12"><Statistic title="一个小目标"><NumberAnimation :to="100000000.12345" /></Statistic></Col><Col :span="12"><Statistic title="一个小目标"><NumberAnimation :to="100000000.12345" separator="" /></Statistic></Col></Row><h2 class="mt30 mb10">精度</h2><Row><Col :span="12"><Statistic title="一个小目标"><NumberAnimation :from="0.00" :to="100000000.12345" :precision="2" /></Statistic></Col><Col :span="12"><Statistic title="一个小目标"><NumberAnimation :to="100000000.12345" :precision="3"/></Statistic></Col></Row><h2 class="mt30 mb10">自定义前缀 & 后缀</h2><Row><Col :span="12"><Statistic title="一个小目标"><NumberAnimationprefix="$":from="0":to="100000000" /></Statistic></Col><Col :span="12"><Statistic title="一个小目标"><NumberAnimation:from="0":to="100000000"suffix="元" /></Statistic></Col></Row><h2 class="mt30 mb10">自定义数值颜色</h2><Row><Col :span="12"><Statistic title="一个小目标"><NumberAnimation color="#1677FF" :from="0" :to="100000000"/></Statistic></Col></Row><h2 class="mt30 mb10">自定义播放和动画时间</h2><Row><Col :span="12"><Statistic title="一个小目标"><NumberAnimationref="animationRef":from="0":to="100000000":duration="5000":precision="2":autoplay="false"@started="onStarted"@finished="onFinished" /></Statistic><Button @click="onClick">播放</Button></Col></Row></div>
</template>