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 } = props
if ( 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= "一个小目标" >
< NumberAnimation
prefix= "$"
: 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= "一个小目标" >
< NumberAnimation
ref= "animationRef"
: from= "0"
: to= "100000000"
: duration= "5000"
: precision= "2"
: autoplay= "false"
@ started = "onStarted"
@ finished = "onFinished" / >
< / Statistic>
< Button @ click = "onClick" > 播放< / Button>
< / Col>
< / Row>
< / div>
< / template>