最常见问题是漏传 start-val 或 duration,导致动画一闪而过;须确保三者类型一致、显式声明且 decimals 匹配小数位数,小程序需用 $nexttick + createselectorquery 获取节点,避免直接调用 countup.js。

u-count-to 参数配错导致动画一闪而过
最常见问题是只传 end-val,漏掉 start-val 或 duration。组件默认 duration 是 300ms,数值大时根本看不出滚动过程。
必须确保三者类型一致且显式声明:
-
start-val和end-val都要是Number,字符串如"1200"会触发NaN -
duration必须是数字,写成"500"会导致内部计算异常 - 要保留小数,
decimals得匹配end-val实际位数,比如end-val="899.6"就得设decimals="1" - 小程序里
autoplay默认为true,但数据常在onLoad后异步到达,建议先设autoplay="false",等this.$nextTick()后再调this.$refs.uCountTo.start()
countUp.js 在小程序报 target is null
这不是代码写错了,是 uni-app 渲染时机和 DOM 节点可用性不一致导致的。直接在 onLoad 里 new CountUp(),节点还没挂载,querySelector 返回 null。
正确做法分两步:等渲染完成 + 拿到真实可操作节点:
- 用
this.$nextTick()确保 Vue 模板已更新 - H5/APP 端可直接用
document.getElementById;小程序端必须走uni.createSelectorQuery().in(this),且加.fields({ node: true }) - 拿到
res.node后不能直接传给原版 countUp.js —— 它不认小程序虚拟节点。要么换用适配版(如countup-weapp),要么降级为手动requestAnimationFrame更新innerText
手写 requestAnimationFrame 滚动时数字超纲或跳帧
自己实现看似自由,但两个坑极易踩中:一是结束判断逻辑错,二是帧调度被干扰。
关键细节:
- 别用
current >= end判断结束,要用elapsed >= duration。帧率波动时,某帧可能算出略超end的值,导致多执行一帧、数字“蹦高” - 缓动函数输出后必须四舍五入再赋值给 data,否则小数累积会让视图抖动(尤其带
decimals="0"时) - 避免把滚动组件塞进
scroll-view。一旦父容器启用scroll-with-animation或频繁触发@scroll,会抢占requestAnimationFrame的调度权,出现卡顿、跳数 - 单位(如 “万”、“亿”)别塞进滚动逻辑,应在模板外用计算属性拼接,否则缓动过程中单位跟着闪
separator 和 use-easing 不是锦上添花,而是体验底线
大屏数据滚动不是炫技,用户扫读效率和信任感直接受这两个参数影响。
separator="," 不只是格式好看:人眼识别 “1,245,678” 比 “1245678” 快 30% 以上;旧版支付宝小程序不支持该属性,得 fallback 到正则:String(num).replace(/\B(?=(\d{3})+(?!\d))/g, ",")。
use-easing 关乎可信度:匀速滚动像电子表倒计时,缓动收尾(尤其是最后 20% 时间明显减速)才让人感觉是真实数据在增长。关掉它,用户容易错过最终数值。
真正难的从来不是让数字动起来,而是让动的过程不干扰数据传达——滚动节奏、千分位、单位位置、结束停顿,每个细节都在悄悄影响信息接收效率。











