uni-app 的 组件动不起来,因其默认静态渲染且三端动画支持不一致;需用 view + transition 或 animation 手动实现,注意 CSS 缓动、单位、兼容性及动画回调差异。

uni-app 的 <progress></progress> 组件为什么动不起来?
因为原生 <progress></progress> 在 uni-app 中默认是静态渲染,percent 变化不会触发动画——它只是个“快照”,不是“动画轨道”。iOS 和部分安卓 WebView 对该组件的 CSS 动画支持极弱,直接改 percent 值只会跳变,没有过渡效果。
真正能动的,是用 view + animation + 数据驱动模拟出来的进度条。官方文档里没明说这点,但实测中 90% 的“进度不动”问题都卡在这儿。
- 别依赖
<progress></progress>的内置动画,它在 H5、小程序、App 三端行为不一致,且多数不生效 - 需要动画,就得手动控制宽度 +
transition或animation - 小程序平台(如微信)对
animationAPI 支持较好,但 H5 端更推荐用 CSStransition避免兼容性坑
用 view 手写一个带缓动的进度条
核心思路:外层固定宽高容器 + 内层动态宽度的 view,靠 style 绑定 width 并加 transition。
<view class="progress-wrap"><view class="progress-inner" :style="{ width: percent + '%', transition: 'width 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94)' }"></view></view>
注意几个关键点:
-
cubic-bezier(0.25, 0.46, 0.45, 0.94)是较顺滑的缓入缓出曲线,比默认ease更自然 - 不要写成
transition: 'all 0.3s',只过渡width避免重排抖动 - 百分比值必须是数字(如
65),不能带%符号,否则绑定失败 - H5 端若遇到跳变,检查是否父容器用了
flex且未设min-width: 0—— 这会导致子元素 width 计算异常
uni-app 中如何让进度条响应式更新?
常见错误是直接在 data 里写死 percent: 0,然后在异步逻辑里 this.percent = 50 —— 这样没问题,但如果你在 onLoad 里立刻赋值,可能因渲染时机导致首次不触发 transition。
稳妥做法:
- 初始化时设为
-1或null,在$nextTick后再设真实值,确保 DOM 已挂载 - 涉及分段加载(如上传进度),用
watch监听percent变化并做防抖,避免高频触发导致卡顿 - 小程序平台可配合
uni.createAnimation实现更精细控制(如回弹、暂停),但 H5 不支持该 API,需条件编译 - 如果进度要“倒退”,记得把
transition放在内层元素上,且不要用transform: scaleX()—— 它在某些安卓 WebView 下会失真
小程序自定义进度条要注意的兼容细节
微信/支付宝小程序里,<progress></progress> 组件虽然支持 activeColor、backgroundColor,但 active 属性只在真机有效,开发者工具里常显示为静态;而且无法修改圆角、阴影、高度等样式。
所以真要自定义外观(比如圆角 8px、带文字、底部描边),必须手写 view 方案,并注意:
- 小程序不支持
background: linear-gradient作为进度条填充色(旧版基础库),可用两层view+ 渐变背景图 hack - 使用
uni.createSelectorQuery()获取容器宽度做响应式适配时,务必加.exec()回调,不能直接链式调用 - App 端(iOS)若出现进度条闪烁,大概率是
web-view渲染层冲突,建议将进度条逻辑移出 web-view,用postMessage通信 - 所有单位统一用
rpx,但border-radius在低版本 iOS 小程序中对rpx解析不准,建议固定写8rpx而非0.5rem
最麻烦的不是写法,而是三端对「动画完成回调」的支持差异——微信小程序有 animationend,H5 有 transitionend,App 端得靠定时器轮询判断,这点很容易被忽略。











