vue实现数字动态滚动
实现数字动态滚动的方案
在Vue中实现数字动态滚动效果,可以通过多种方式实现。以下是几种常见的方法:
使用CSS动画
通过CSS的transition或animation属性实现数字变化时的平滑过渡效果。这种方法简单但控制粒度较粗。
<template>
<div class="animated-number">{{ currentValue }}</div>
</template>
<script>
export default {
data() {
return {
currentValue: 0,
targetValue: 100
}
},
mounted() {
this.animateNumber()
},
methods: {
animateNumber() {
const duration = 2000 // 动画持续时间
const startTime = performance.now()
const updateValue = (timestamp) => {
const elapsed = timestamp - startTime
const progress = Math.min(elapsed / duration, 1)
this.currentValue = Math.floor(progress * this.targetValue)
if (progress < 1) {
requestAnimationFrame(updateValue)
}
}
requestAnimationFrame(updateValue)
}
}
}
</script>
<style>
.animated-number {
transition: all 1s ease-out;
}
</style>
使用第三方库
Vue-count-to是一个专门用于数字动画的Vue组件,提供更多配置选项。
安装:
npm install vue-count-to
使用示例:
<template>
<countTo :startVal="0" :endVal="1000" :duration="3000"></countTo>
</template>
<script>
import countTo from 'vue-count-to'
export default {
components: { countTo }
}
</script>
自定义动画函数
对于更复杂的动画需求,可以创建自定义动画函数,结合requestAnimationFrame实现。
<template>
<div>{{ animatedValue }}</div>
</template>
<script>
export default {
data() {
return {
startValue: 0,
endValue: 1000,
duration: 2000,
animatedValue: 0
}
},
mounted() {
this.startAnimation()
},
methods: {
startAnimation() {
let startTimestamp = null
const step = (timestamp) => {
if (!startTimestamp) startTimestamp = timestamp
const progress = Math.min((timestamp - startTimestamp) / this.duration, 1)
this.animatedValue = Math.floor(
this.startValue + progress * (this.endValue - this.startValue)
)
if (progress < 1) {
requestAnimationFrame(step)
}
}
requestAnimationFrame(step)
}
}
}
</script>
实现细节优化
缓动函数应用

为动画添加缓动效果可以使滚动更自然。常用的缓动函数包括easeInOutQuad、easeOutCubic等。
// 缓动函数示例
function easeOutCubic(t) {
return 1 - Math.pow(1 - t, 3)
}
// 在动画函数中使用
const easedProgress = easeOutCubic(progress)
this.animatedValue = Math.floor(
this.startValue + easedProgress * (this.endValue - this.startValue)
)
格式化显示
对于大数字,可以添加千位分隔符或货币符号等格式化显示。
methods: {
formatNumber(value) {
return value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")
}
}
响应式更新
当目标值变化时自动触发新动画,可以添加watch监听。

watch: {
endValue(newVal) {
this.startValue = this.animatedValue
this.endValue = newVal
this.startAnimation()
}
}
性能考虑
减少DOM操作
避免在动画过程中频繁操作DOM,使用虚拟DOM的特性让Vue批量处理更新。
使用will-change
对动画元素应用CSS will-change属性,提示浏览器优化。
.animated-number {
will-change: contents;
}
适时停止动画
在组件销毁前取消未完成的动画帧请求。
beforeDestroy() {
cancelAnimationFrame(this.animationFrameId)
}
以上方法可以根据具体需求选择或组合使用,实现从简单到复杂的数字滚动效果。






