只有app端(ios/android)支持用svg实现自定义下拉刷新动画,h5和小程序因依赖系统原生控件,svg会被忽略或渲染异常;必须禁用原生方案,改用scroll-view的refresher插槽内联svg,并通过refresher-default-style="none"、refresher-triggered绑定及事件控制显隐与状态流转。

App端才能用SVG做下拉刷新动画
只有 App(iOS/Android)平台支持真正意义上的自定义下拉刷新 UI,H5 和小程序走的是系统原生控件,SVG 会被忽略或渲染异常。想用 SVG 动画,必须放弃 enablePullDownRefresh + onPullDownRefresh 的原生方案,改用 scroll-view 的自定义 refresher 模式。
用 scroll-view + refresher 插槽塞 SVG
核心是禁用默认样式,把 SVG 放进 #refresher 插槽里,再通过事件控制显隐和状态流转:
-
refresher-default-style="none"必须设,否则 SVG 会被原生 loading 覆盖 -
refresher-triggered绑定一个响应式变量(如isRefreshing),松手触发@refresherrefresh后置为true,请求完成再设为false,让 refresher 自动复位 -
refresher-threshold建议设为60,太小容易误触,太大用户感知弱 - SVG 最好用内联方式写(不要
<img src="xxx.svg">),确保在不同分辨率下缩放一致;加width="48rpx" height="48rpx"控制尺寸
<scroll-view refresher-enabled="true" refresher-threshold="60" refresher-default-style="none" :refresher-triggered="isRefreshing"><template><view class="refresher-box"><svg viewbox="0 0 100 100" width="48rpx" height="48rpx"><circle cx="50" cy="50" r="40" fill="none" stroke="#007AFF" stroke-width="4" stroke-dasharray="251.2" stroke-dashoffset="0"></circle><path d="M50,10 Q70,10 70,30 Q70,50 50,50 Q30,50 30,30 Q30,10 50,10 Z" fill="#007AFF"></path></svg><text class="refresher-text">{{ refreshText }}</text></view></template></scroll-view>
手动控制 SVG 动画节奏要靠 CSS transform + transition
原生 refresher 不提供拖动过程中的实时 deltaY,所以无法让 SVG 随手指线性旋转或缩放。只能分三阶段控制:
- 下拉中(
@refresherpulling):设transform: scale(0.9)或轻微旋转rotate(-5deg),提示“可释放” - 释放瞬间(
@refresherrefresh):立刻切到transform: rotate(0deg)+animation: spin 1s linear infinite - 恢复时(
@refresherrestore):清空 animation,还原 scale 和 rotate
注意:@refresherpulling 在 H5 端不触发,仅 App 有效;iOS 上需开启 bounce="true" 才有触顶反馈。
容易漏掉的兼容细节
SVG 在部分 Android 机型(尤其旧版 EMUI、MIUI)可能渲染模糊或不显示,原因有二:
- 未设置
viewBox导致缩放失真 —— 必须写viewBox="0 0 100 100"并配合width/height - 父容器没设
overflow: visible——scroll-view默认裁剪,要在.refresher-box加style="overflow: visible" -
uni-app 编译后 SVG 内联样式可能被剥离 —— 把
fill、stroke写在标签属性里,别用style=""
真机调试时优先跑 iOS,Android 下拉距离阈值更敏感,refresher-threshold 设高一点更稳。











