uni-app原生progress组件不支持渐变+动画双效果,需用view+linear-gradient或canvas手动实现;h5端因默认background-color覆盖渐变,小程序端不支持background-image,正确写法需用90deg和transparent !important。

uni-app 里原生 progress 组件不支持渐变 + 动画双效果,强行绑定 percent 或加 CSS 渐变只会失效或卡顿——必须绕开它,用 view + linear-gradient 或 canvas 手动实现。
为什么 progress 加 background-image: linear-gradient() 没反应
因为 H5 端 uni-app 会注入默认 background-color 样式,直接盖掉你的渐变;小程序端则压根不支持给 progress 设置 background-image。即使写了 to right,也得改成 90deg 才生效,且必须显式声明 background-color: transparent !important。
- 错误写法:
background: linear-gradient(to right, #007AFF, #4CD964)→ 被覆盖,无效果 - 正确写法:
background: linear-gradient(90deg, #007AFF, #4CD964); background-color: transparent !important; - 真机调试时若渐变只显示一半,大概率是父容器
overflow: hidden没设,或width计算错(比如用了v-bind:style="{ width: percent + '%' }"但没限制父容器宽度)
用 view 实现带过渡的线性渐变进度条(推荐 H5 + 小程序通用)
核心是两个嵌套 view:外层做遮罩和背景,内层用 background-image + transition: width 控制填充动画。比 Canvas 更轻、更易维护。
- 模板结构:
<view class="progress-bar"><view class="progress-inner" :style="{ width: current + '%' }"></view></view> - CSS 关键点:
.progress-bar { height: 8px; background-color: #f0f0f0; border-radius: 4px; overflow: hidden; } .progress-inner { height: 100%; background: linear-gradient(90deg, #007AFF, #4CD964); width: 0%; transition: width 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94); } - 务必校验
current值:赋值前用Math.max(0, Math.min(100, Number(val))),否则NaN会导致width变成NaN%,整个条消失
用 canvas 实现环形渐变进度条(适合高定制、多端一致)
Canvas 是唯一能跨端稳定输出径向/线性渐变圆弧的方案,尤其适合“砍价”类动态环形进度。注意:微信/支付宝/字节系小程序都支持 uni.createCanvasContext,但 H5 端需额外处理 DPR 缩放。
- 关键步骤:
- 用
ctx.createLinearGradient(x1,y1,x2,y2)定义渐变方向(不是to bottom这种 CSS 写法) - 调用
gradient.addColorStop(0, '#ff6b6b')和gradient.addColorStop(1, '#4ecdc4')插入色标 - 绘制圆弧时,
ctx.setStrokeStyle(gradient),不是setFillStyle - 动画靠
requestAnimationFrame驱动,每次重绘前先ctx.clearActions(),否则残留旧帧
- 用
- 常见坑:
startAngle和endAngle单位是弧度,别直接用百分比;strokeLinecap: 'round'必须设,否则两端有尖角
真机上进度条“跳变”或“不动”的典型原因
不是代码写错,而是生命周期或数据流出了问题。
-
onReady里调用drawProgress但没等 DOM 渲染完成 → 改用$nextTick包一层 - 异步任务(如上传)中直接
this.current = 100→ 必须拆成setTimeout或requestAnimationFrame分步赋值,例如每 30ms +1% - Android 低端机不识别
rgb(0, 122, 255)→ 所有颜色统一用十六进制,如#007AFF - 支付宝小程序要求
stroke-width必须带单位("6rpx"),微信可省略 → 跨平台请始终写全单位
渐变本身没问题,问题永远出在“谁在什么时候改了什么值”——盯着 current 的变更路径,比调样式更管用。











