导读:本期聚焦于唐僧创作的《微信小程序怎么自定义下拉刷新的loading样式、背景色和文字颜色?》,敬请观看详情。下拉刷新停在页面顶部时,默认的白色背景和深色loading在深色主题里会显得很突兀,但原生页面级配置能改的范围其实很有限。小程序原生下拉刷新只开放了 backgroundColor 和 backgroundTextStyle 两个样式入口,其中 backgroundTextStyle 仅支持 dark 与 light 两种明暗状态,无法设置任意十六进制颜色,loading 动画更是系统内置样式。如果产品要求换掉旋转图标、改成进度环,或者让刷新区域的文字颜色与品牌色一致,就需要把思路从页面配置切换到 scroll-view 的 refresher 插槽。借助 refresher-enabled、refresher-triggered、refresher-background 以及 refresher 插槽,可以完全自定义 loading 区域的结构、背景色和文字颜色。本文从原生配置边界讲起,给出可运行的 WXML 与 JS 示例,再说明真机调试时的兼容性差异和常见偏移问题,帮助你一次性把下拉刷新做成符合设计稿的样式。

在小程序里做下拉刷新,开启页面级刷新只需要在 JSON 配置里加上 enablePullDownRefresh,但很多项目在设计稿中要求 loading 图标、背景色、文字颜色全部与品牌风格统一。原生能力只能覆盖其中一部分,想做到完全自定义就必须理解配置边界,并换成 <scroll-view> 的 refresher 方案。下面先把原生配置能改哪些样式理清楚,再给出可落地的自定义实现。

微信小程序怎么自定义下拉刷新的loading样式、背景色和文字颜色?

一、原生下拉刷新的样式边界

页面级下拉刷新依靠 JSON 文件中的三个配置项来调整基础外观。enablePullDownRefresh 负责开启下拉刷新,backgroundColor 指定刷新区域的背景色,backgroundTextStyle 控制刷新文字和系统 loading 图标的明暗,可选值只有 dark 和 light。也就是说,原生方案无法把 loading 图标替换成自定义动画,也不能把提示文字设置为任意颜色,只能根据背景深浅选择黑或白。

在单个页面配置时,可以直接在页面对应的 JSON 文件中写入:

{
  "enablePullDownRefresh": true,
  "backgroundTextStyle": "dark",
  "backgroundColor": "#f5f5f5"
}

如果希望整个小程序所有页面都启用下拉刷新,可以在 app.json 的 window 字段中进行全局设置。例如深色页面想使用浅色 loading 文字,可以这样写:

{
  "window": {
    "enablePullDownRefresh": true,
    "backgroundTextStyle": "light",
    "backgroundColor": "#1f1f1f"
  }
}

这里有一个容易踩中的点:backgroundTextStyle 并不是任意 CSS 颜色值,传入 #ff6600 这样的写法在真机上不会生效,只会被当成非法值处理。因此原生配置更适合做简单的明暗适配,不适合做品牌色定制。如果设计稿要求 loading 区域背景为暖色、文字为品牌蓝,就需要跳出页面配置,改用 <scroll-view> 提供的自定义刷新能力。

二、用 scroll-view 的 refresher 插槽自定义 loading

基础库 2.10.1 开始,<scroll-view> 组件增加了 refresher 相关属性,其中最核心的是 refresher-enabled、refresher-triggered、refresher-background 和 refresher-default-style。配合 slot="refresher" 插槽,可以把系统默认刷新区域完全替换成自定义结构,实现在刷新区域放任意动画、图标和文案。

下面是一段 WXML 示例,展示如何用插槽放置一个旋转圆环和动态文字:

<scroll-view
  scroll-y
  refresher-enabled
  refresher-triggered="{{triggered}}"
  refresher-threshold="{{80}}"
  refresher-background="#f9f9f9"
  refresher-default-style="black"
  bindrefresherrefresh="onRefresh"
  bindrefresherrestore="onRestore"
  bindrefresherabort="onAbort"
  class="scroll-wrap"
>
  <view slot="refresher" class="custom-refresh">
    <view class="spinner" style="background-color: {{loadingBg}};"></view>
    <text style="color: {{textColor}};">{{loadingText}}</text>
  </view>
  <view class="content">
    <block wx:for="{{list}}" wx:key="id">
      <view class="item">{{item.name}}</view>
    </block>
  </view>
</scroll-view>

对应的 JS 逻辑需要维护 triggered 状态,并在刷新结束后手动复位,否则 <scroll-view> 会一直停留在刷新中。下面这段代码模拟了 1.8 秒的异步刷新过程:

Page({
  data: {
    triggered: false,
    loadingBg: '#ff6600',
    textColor: '#333333',
    loadingText: '下拉刷新',
    list: []
  },
  onRefresh() {
    if (this.data.triggered) return;
    this.setData({ triggered: true, loadingText: '正在加载最新数据...' });
    setTimeout(() => {
      this.setData({
        triggered: false,
        loadingText: '刷新完成',
        list: [
          { id: 1, name: '新内容一' },
          { id: 2, name: '新内容二' }
        ]
      });
      wx.showToast({ title: '刷新成功', icon: 'success' });
    }, 1800);
  },
  onRestore() {
    this.setData({ loadingText: '下拉刷新' });
  },
  onAbort() {
    this.setData({ triggered: false, loadingText: '下拉刷新' });
  }
});

自定义区域是否能顺畅展示,关键在于 refresher-threshold 与 .custom-refresh 高度之间的配合。通常将阈值设为 80 左右,同时把插槽容器高度控制在 60 到 80 之间,松开后动画就不会出现明显跳动。另外,refresher-triggered 必须绑定到 data 中,不要尝试直接在 WXML 中写死布尔值,否则事件回调无法驱动 UI 状态变化。

三、背景色与文字颜色的详细配置

从可配置范围看,原生 JSON 只能通过 backgroundColor 控制刷新区域背景,且该颜色会覆盖在页面背景之上。文字颜色则受 backgroundTextStyle 约束,只支持 dark 或 light。如果页面本身的背景是渐变、图片或深色卡片,原生下拉刷新露出时就会有一条明显色块,视觉上很难统一。

改用 scroll-view 后,refresher-background 可以直接设置任意十六进制颜色或 rgba 值,文字颜色则完全由插槽内 <text> 的 style 决定,可以绑定动态变量实现深色模式切换。比如在夜间模式时把 loadingBg 改为 #ffffff,把 textColor 改为 #dddddd,再把 refresher-background 绑定到变量即可。

样式部分可以配合 CSS 动画做出圆形进度效果:

.scroll-wrap {
  height: 100vh;
  background: #ffffff;
}
.custom-refresh {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 80px;
  padding-top: 20px;
}
.spinner {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  border: 2px solid rgba(0, 0, 0, 0.1);
  animation: spin 0.8s linear infinite;
}
@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

需要注意的是,基础库低于 2.10.1 的版本不支持 refresher 插槽,此时想要完全自定义 loading 只能通过监听页面 touch 事件、自己实现一个下拉容器来完成。这种手写方案要处理触摸距离、回弹动画和触发阈值,代码量明显增加,因此在支持新基础库的项目中优先使用 scroll-view 方案会更稳定。

四、常见问题与兼容性避坑

第一个常见问题是原生下拉刷新和 scroll-view 下拉刷新同时开启。页面 JSON 里如果已经配置了 enablePullDownRefresh,又在页面内使用带 refresher 的 scroll-view,很容易出现同时触发两次刷新的情况。一般建议页面级下拉刷新只在非滚动容器场景使用,列表页采用 scroll-view 自定义刷新时,应关闭页面级配置。

第二个问题是刷新结束后 loading 不消失。无论请求成功还是失败,只要 refresher-triggered 为 true,就必须在异步回调中将其设置为 false。如果有多个并发请求,建议用计数器或 Promise.all 来判断全部完成后再复位。

第三点是真机上的文字颜色可能比开发者工具浅或者深,尤其是使用 rgba 透明背景时,不同系统渲染会有差异。调试时最好在 iOS 和 Android 真机上分别查看,避免只在工具里通过。最后还要检查刷新区域与页面顶部安全区的关系,在刘海屏设备上可以给自定义插槽增加 env(safe-area-inset-top) 的 padding,让 loading 不被状态栏遮挡。

微信小程序下拉刷新自定义loading样式修改时间:2026-09-27 17:57:02

免责声明:已尽一切努力确保本网站所含信息的准确性。网站作品多为原创整理与精心创作,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们进行处理Email:chomcom@qq.com。
引用或转载本作品时,请注明当前出处:https://www.ipipp.com/html/0927/62647.html,基于非商业用途的前提下,欢迎转载或二创本作品。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。