纯CSS Loading组件需用border-top-color单设色、transform-origin:center居中、v-show控制显隐;color/size通过:style绑定,单位用rpx,动画时长0.6s,配合scale解决DPR模糊。

怎么用 CSS 写一个支持 color 和 size 的 Loading 组件
直接用纯 CSS 实现最轻量、最可控,也避免了第三方库在多端兼容上的坑。关键不是“怎么动”,而是“怎么让动得稳、改得准”。
-
v-show必须代替v-if,否则每次显隐都会重置动画计时器,转一半就停 - 旋转中心必须显式设
transform-origin: center,否则在某些安卓 WebView 里会偏移抖动 -
border-top-color单独设色比用border-color更可靠,能确保只有一段高亮,形成经典“旋转圆环”效果 - 传入的
color值要同时作用于border-top-color和border-right-color(或仅 top),不然颜色不一致 - 尺寸用
width/height控制,别只调border-width,否则缩放后比例失真
为什么 props 传色后没生效?常见样式隔离问题
scoped 样式下,:deep(.loading) 不起作用是常态——因为 .loading 是组件内部元素,不是子组件根节点。真正有效的是 ::v-deep 或去掉 scoped。
- 如果用了
<style scoped>,必须写成::v-deep(.loading) { border-top-color: v-bind(color); } - H5 端支持
v-bind()动态绑定 CSS 变量,但小程序不支持,得靠 class 切换或内联 style - 更稳妥的做法:把 color 和 size 提前算好,通过
:style直接绑定到<view class="loading">上,例如::style="{ borderTopColor: color, width: size, height: size }" - 注意单位:传
"40rpx"比40安全,避免单位缺失导致 iOS 端渲染异常
App 和小程序里动画卡顿/模糊怎么办
Canvas 渲染层和 CSS 渲染层混用时,DPR(设备像素比)不匹配是主因。尤其在 iPhone 或高分屏安卓机上,200rpx 的圆环可能只占 100 物理像素,结果锯齿明显。
- 不要只写
width: 200rpx,加一行transform: scale(2)并配transform-origin: center,再把原始尺寸缩小一半 - 动画时长统一设为
0.6s,太慢显得迟滞,太快又看不清;小程序对animation-duration的解析精度不如 H5,0.6s 比 1s 更稳 - 避免用
opacity: 0隐藏加载层,得同步加pointer-events: none,否则点击穿透到下层按钮 - App 端 nvue 页面若用原生渲染,CSS 动画支持有限,优先用
animation而非transition,后者在部分 Android 机型上失效
全局调用时怎么避免重复挂载或状态错乱
挂载到 Vue.prototype 后,this.$showLoading() 看似方便,但多个页面并发调用时容易覆盖 loading 状态,比如 A 页面还没 hide,B 页面又 show,结果关不掉。
- 推荐用 Vuex/Pinia 管理单一 loading 状态,
showLoading做累加计数,hideLoading减一,仅当计数归零才真正隐藏 - 不要在
mounted里自动 show,除非明确是页面初始化加载;多数场景应由业务逻辑触发 - 如果用 ref 方式(如
<loading ref="loading">),务必确认 ref 已挂载再调用方法,否则真机报undefined is not a function - App 端冷启动时,
main.js中注册组件早于 Vue 实例初始化,需确保Vue.component在new Vue()之前执行


















