APIs
NumberAnimation
参数 |
说明 |
类型 |
默认值 |
from |
数值动画起始数值 |
number |
0 |
to |
数值目标值 |
number |
1000 |
duration |
数值动画持续时间,单位 ms |
number |
3000 |
autoplay |
是否自动开始动画 |
boolean |
true |
precision |
精度,保留小数点后几位 |
number |
0 |
prefix |
前缀 |
string |
undefined |
suffix |
后缀 |
string |
undefined |
separator |
千分位分隔符 |
string |
‘,’ |
decimal |
小数点字符 |
string |
‘.’ |
valueStyle |
数值文本样式 |
CSSProperties |
{} |
transition |
动画过渡效果 |
TransitionFunc |
TransitionFunc[‘easeInOutCubic’] |
Methods
事件名称 |
说明 |
参数 |
play |
播放动画 |
() => void |
Events
事件名称 |
说明 |
参数 |
started |
动画开始播放 |
() => void |
finished |
动画播放完成 |
() => void |
安装依赖:
pnpm add @vueuse/core
创建数值动画组件NumberAnimation.vue
其中引入使用了以下工具函数:
<script setup lang="ts">
import { ref, computed, watchEffect, onMounted, watch } from 'vue'
import type { CSSProperties } from 'vue'
import { formatNumber } from '../utils'
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 // 数值动画持续时间,单位 ms
autoplay?: boolean // 是否自动开始动画
precision?: number // 精度,保留小数点后几位
prefix?: string // 前缀
suffix?: string // 后缀
separator?: string // 千分位分隔符
decimal?: string // 小数点字符
valueStyle?: CSSProperties // 数值文本样式
transition?: TransitionFunc // 动画过渡效果
}
const props = withDefaults(defineProps<Props>(), {
from: 0,
to: 1000,
duration: 3000,
autoplay: true,
precision: 0,
prefix: undefined,
suffix: undefined,
separator: ',',
decimal: '.',
valueStyle: () => ({}),
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(() => {
const { precision, separator, decimal, prefix, suffix } = props
return formatNumber(outputValue.value, precision, separator, decimal, prefix, suffix)
})
const emits = defineEmits(['started', 'finished'])
defineExpose({
play
})
</script>
<template>
<span :style="valueStyle">
{
{ 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 :value-style="{fontSize: '30px', fontWeight: 600, color: '#d4380d'}" :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>