ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

uni-app x 自定义下拉刷新组件 uni-refresh-box 完整实战指南

2026/9/21 1:19:13 拓冰建站 浏览量
uni-app x 自定义下拉刷新组件 uni-refresh-box 完整实战指南 示例工程前端移动开发跨平台【免费下载链接】uni-appA cross-platform framework using Vue.js项目地址https://gitcode.com/gh_mirrors/un/uni-app点击查看免费下载uni-refresh-box 是 uni-app x含 App、Web、小程序、鸿蒙等多端下的 uni ext component 自定义下拉刷新组件用于封装 scroll-view、list-view 等滚动容器的下拉刷新能力。本文将以本仓库中该组件的官方文档为骨架结合组件真实源码 uni-refresh-box.vue 与仓库内示例页完整讲解其属性、状态机、插槽自定义、滚动容器配合方式与四种典型实战形态让读者既能直接照抄可用代码也能理解其底层工作机理。组件定位把“下拉刷新”这件事彻底交给你默认情况下各平台滚动容器自带的下拉刷新样式是固定的难以做品牌化定制。uni-refresh-box 解决的就是这一问题它把下拉刷新的“反馈 UI”完全组件化使用者在滚动容器中放入本组件通过属性控制文字与样式甚至通过插槽传入完全不同的自定义下拉效果。本组件自带一套全平台通用的默认样式左边一个 loading 转圈右边跟随状态切换提示文字。在此基础上它提供了多层次的定制能力文字层通过pullingText、loosingText、loadingText、completeText分别控制下拉中、松手可刷新、刷新中、刷新完成四个阶段的文案样式层通过textClass、loadingClass传入外部样式类控制文字与 loading 图标的观感插槽层通过loading插槽传入任意自定义图标或动图实现完全不同的下拉效果。组件本质是一个“状态展示器”它不负责手势识别而是接收滚动容器通过refresher插槽传入的下拉距离与刷新状态从而把“滚动容器的刷新机制”与“刷新视觉呈现”解耦。快速上手基本用法在页面中引入组件后在 scroll-view或 list-view内放置uni-refresh-box并传入pulling-distance与refreshing两个核心属性即可template scroll-view styleflex: 1; :refresher-enabledtrue :refresher-triggeredrefreshing1 refresher-default-stylenone :refresher-threshold45 refresher-max-drag-distance200px refresherpullingonRefresherpulling1 refresherrefreshonRefresherrefresh1 refresherrestoreonRefresherrestore1 refresherabortonRefresherabort1 !-- 列表内容 -- view v-fori in listCount1 :keyi classcontent-item text classtextitem-{{ i }}/text /view !-- refresher 插槽使用 uni-refresh-box 组件 -- uni-refresh-box slotrefresher :pulling-distancepullingDistance1 :refreshingrefreshing1 /uni-refresh-box /scroll-view /template script setup languts const listCount1 ref(3) const refreshing1 ref(false) const pullingDistance1 ref(0) function onRefresherpulling1(e: RefresherEvent) { pullingDistance1.value e.detail.dy } function onRefresherrefresh1() { refreshing1.value true console.log(列表1 触发刷新) setTimeout(() { listCount1.value 5 refreshing1.value false console.log(列表1 刷新完成) }, 1500) } function onRefresherrestore1() { pullingDistance1.value 0 } function onRefresherabort1() { pullingDistance1.value 0 } /script这段代码中的数据流是完整闭环的滚动容器开启下拉刷新refresher-enabled并关闭系统默认样式refresher-default-stylenone腾出位置给自定义组件用户下拉时refresherpulling携带e.detail.dy下拉距离单位 px页面将其写入pullingDistance1通过:pulling-distance回传给 uni-refresh-box下拉超过阈值refresher-threshold45松手后refresherrefresh触发页面置refreshing1 true组件随即切换为“刷新中”状态数据加载完成示例中用setTimeout模拟 1.5 秒后置refreshing1 false并依赖refresherrestore/refresherabort将下拉距离归零组件随之复位。注意slotrefresher必须书写在组件的外层标签上。仓库示例中还特别注释了两条平台差异Android 不支持 bool 属性简写refresher-enabledtrue不能简写为refresher-enabledWeb 端只认组件外层使用slotrefresher不支持组件内部根元素上书写。状态机04 五种状态的驱动逻辑组件对外暴露一个核心概念state 状态。文档中给出了明确的状态定义值说明0下拉中未达到阈值1松手可刷新已达到阈值2刷新中3刷新完成4归位中不显示文字从源码 uni-refresh-box.vue 可以看到这五种状态并非由组件凭空生成而是由pullingDistance、threshold、refreshing三个输入实时计算出来的const currentState computed((): number { if (resetting.value) { return 3 } if (props.refreshing) { return 2 } // 归位中不显示文字 if (restoring.value) { return 4 } if (props.pullingDistance props.threshold) { return 1 } return 0 })状态判定优先级为刷新完成3 刷新中2 归位中4 松手可刷新1 下拉中0。其中resetting与restoring两个内部标记配合refreshing的回落完成状态过渡当外部把refreshing从true改为false时组件先进入“刷新完成”状态3并展示completeText300ms 后清除resetting标记源码 L107-L116之后进入“归位中”状态4该阶段不显示任何文字直到下拉距离归零restoring被清除。提示文字tipText由状态值映射而来源码 L89-L104const tipText computed((): string { switch (currentState.value) { case 0: return props.pullingText case 1: return props.loosingText case 2: return props.loadingText case 3: return props.completeText case 4: return // 归位中不显示文字 default: return props.pullingText } })理解状态机的意义页面侧无需自行判断“该显示哪句话”只需如实上报下拉距离与刷新布尔值所有文案切换逻辑都在组件内完成这也是自定义刷新组件最省心的用法。属性详解参数、默认值与底层行为文档属性表完整如下与源码 Props 定义 一一对应| 名称 | 类型 | 默认值 | 描述 | | :- | :- | :- | :- | | pullingDistance | number | 0 | 当前下拉距离px通常由外部 scroll-view 的 refresher 状态传入 | | refreshing | boolean | false | 是否正在刷新中外部控制为 true 时显示 loading 动画 | | threshold | number | 45 | 触发刷新的下拉阈值px下拉距离超过该值时进入“松手刷新”状态 | | pullingText | string | 下拉刷新 | 下拉过程中未达到阈值显示的提示文字 | | loosingText | string | 松手刷新 | 下拉超过阈值后显示的提示文字 | | loadingText | string | 正在刷新 | 刷新中显示的提示文字 | | completeText | string | | 刷新完成瞬间显示的提示文字为空则不展示 | | textClass | string(string.ClassString) | | 提示文字的自定义样式类 | | loadingClass | string(string.ClassString) | | loading 图标的自定义样式类 |逐项说明pullingDistance / threshold / refreshing是组件的“输入三件套”。threshold的默认值 45 与滚动容器refresher-threshold的推荐取值保持一致二者应设为相同数值否则会出现“容器已触发刷新、组件仍显示松手提示”的不同步观感。pullingText / loosingText / loadingText / completeText覆盖了状态机中 03 的文案状态 4归位中固定不显示文字不受任何属性控制。textClass / loadingClass的类型是 UTS 的string.ClassStringIDE 字符串其生效机制是组件的externalClasses源码 L11-L13——即类名定义在组件外部、但作用在组件内部节点上与常规的 class 透传行为一致。传入textClass会作用在提示文字text上loadingClass会作用在默认 loading 圈上。默认视觉与内置样式组件内置样式源码 L146-L166决定了零配置时的外观容器.uni-refresh-box-buildin宽度 100%、高度 30px、横向排列并居中loading 圈.uni-loading-class-buildin14×14px、边框色#888文字.uni-text-class-buildin14px、颜色#888、左侧 4px 间距。下拉过程的旋转反馈组件对pullingDistance的监听还附带一个细节下拉过程中默认 loading 圈会随距离旋转源码 L119-L138const maxDistance 200 const maxRotation 540 const rotation Math.min((distance / maxDistance) * maxRotation, maxRotation) el.style.setProperty(transform, rotate(${rotation}deg))即下拉距离从 0 到 200pxloading 圈最多旋转 540 度1.5 圈超出后封顶刷新中refreshing为 true时不执行此旋转逻辑。若需改变旋转灵敏度可在滚动容器侧调整refresher-max-drag-distance。插槽自定义loading 插槽与 state 参数当默认的“loading 圈 文字”形态无法满足需求时可使用loading插槽完全替换左侧图标插槽参数为当前状态值state名称说明插槽参数loading自定义图标state当前状态值 04源码中插槽默认内容为内置 loading源码 L3-L5slot nameloading :statecurrentState loading refloadingRef :pausedcurrentState ! 2 classuni-loading-class-buildin :classloadingClass bold/loading /slot注意两点底层行为默认 loading 的:pausedcurrentState ! 2意味着只有刷新中state 2时转圈才真正旋转插槽参数state让自定义图标也能依据状态切换图片或动画例如“下拉中显示静态箭头、刷新中显示转圈动图”。实战形态一暗黑竖排自定义文字默认布局是横向“左图标右文字”。通过覆盖容器样式与外部类可改成竖排、深色背景下的白字形态对应仓库官方示例第二段scroll-view styleflex: 1;background-color: black; :refresher-enabledtrue :refresher-triggeredrefreshing2 refresher-default-stylenone :refresher-threshold45 refresher-max-drag-distance200px refresherpullingonRefresherpulling2 refresherrefreshonRefresherrefresh2 refresherrestoreonRefresherrestore2 refresherabortonRefresherabort2 !-- 列表内容 -- view v-fori in listCount2 :keyi classcontent-item text classtextitem-{{ i }}/text /view uni-refresh-box slotrefresher :pulling-distancepullingDistance2 :refreshingrefreshing2 loading-classloading-dark text-classtext-dark styleflex-direction: column;height: 46px;padding-top: 6px; pulling-text继续下拉可刷新 loosing-text释放后会刷新 loading-text奋力加载中... /uni-refresh-box /scroll-view配套样式类.loading-dark{ border-color: white; width: 20px; height: 20px; } .text-dark{ color: white; margin-top: 5px; }关键点在组件上直接写styleflex-direction: column;即可覆盖内置横向布局同时通过text-class、loading-class将组件内部文字与 loading 圈改为白色、加大尺寸三段文案属性被替换为更贴合场景的文案。实战形态二插槽完全自定义图标使用loading插槽替换默认转圈例如接入外部动图对应官方示例第三段uni-refresh-box slotrefresher :pulling-distancepullingDistance3 :refreshingrefreshing3 template #loading{ state } image v-ifstate 2 srchttps://web-ext-storage.dcloud.net.cn/hello-uni-app-x/refresh-box-run.gif stylewidth: 20px; height: 20px; / !-- 刷新中的动图-- image v-else srchttps://web-ext-storage.dcloud.net.cn/hello-uni-app-x/refresh-box-run.gif stylewidth: 20px; height: 20px; / !-- 非刷新中的图可以和刷新中的图是一张也可以分开-- /template /uni-refresh-box插槽解构出{ state }后可依据状态值04渲染不同图片state 2表示刷新中此时展示旋转动图其余状态展示静态图也可以与刷新中同图或按需求细分。这样便实现了与默认形态完全不同的品牌化下拉效果而无需改动滚动容器任何逻辑。实战形态三无文字纯 loading若希望只保留图标、去掉全部文字将三段文字属性置空即可对应官方示例第四段uni-refresh-box slotrefresher :pulling-distancepullingDistance4 :refreshingrefreshing4 pulling-text loosing-text loading-text loading-classloading-big-font /uni-refresh-box配合loading-class放大图标尺寸.loading-big-font{ width: 24px; height: 24px; }文字置空后状态机仍然照常驱动状态 4 归位中本就无文字页面视觉只剩一个随状态旋转/暂停的 loading 圈。与滚动容器的配合scroll-view / list-view 的 refresher 体系uni-refresh-box 必须挂在滚动容器的refresher插槽中才能工作。滚动容器侧需要配置的属性与事件详见 scroll-view 组件文档 与 list-view 组件文档关键属性| 属性 | 作用 | 与组件的关系 | | :- | :- | :- | | refresher-enabled | 是否开启下拉刷新 | 必须为 true | | refresher-triggered | 刷新状态外部布尔值 | 与组件refreshing绑定同一变量 | | refresher-default-style | 系统默认刷新样式 | 必须设为none以隐藏系统样式 | | refresher-threshold | 触发阈值px | 与组件threshold保持一致 | | refresher-max-drag-distance | 最大拖拽距离 | 影响组件 loading 旋转速度 | | refresher-background | 刷新区域背景色 | 可选见下 |核心事件| 事件 | 触发时机 | 推荐处理 | | :- | :- | :- | | refresherpulling | 下拉过程中e.detail.dy为当前下拉距离 | 写入 pullingDistance | | refresherrefresh | 达到阈值松手触发刷新 | 置 refreshing true发起数据请求 | | refresherrestore | 刷新结束复位 | 将 pullingDistance 归零 | | refresherabort | 未达阈值松手刷新被中止 | 将 pullingDistance 归零 |仓库示例页 scroll-view-refresher-props.uvue 演示了这些属性的运行时调节可通过开关切换refresher-enabled、输入框调整refresher-threshold与refresher-background、按钮在none/black/white间切换refresher-default-style其日志清晰地反映了“下拉 → 触发 → 复位 → 中止”四类事件的发生时机。该页同时提示下拉刷新的属性设置需要先打开下拉刷新开关且不能同时关闭下拉状态与关闭下拉刷新。在 list-view 中用法完全一致仓库示例 custom-refresher.uvue 展示了 list-view sticky-header 自定义 refresher 的组合并给出了一种页面侧自行计算状态的替代方案const state computed(() : number { if (resetting.value) return 3 if (refresherTriggered.value) return 2 if (pullingDistance.value refresherThreshold.value) return 1 return 0 })这与 uni-refresh-box 源码中的currentState计算逻辑完全同构可作为理解组件内部状态机的最佳参考。兼容性| Web | 微信小程序 | Android | iOS | HarmonyOS | | :- | :- | :- | :- | :- | | 5.07 | 5.07 | 5.07 | 5.07 | 5.07 |作为 uni ext component需在插件市场安装 uni-refresh-box 插件其兼容范围覆盖 uni-app x 支持的全部主要平台。组件自身在 App 端Android/iOS、Web 端、微信小程序端与鸿蒙端均有对应的滚动容器 refresher 机制支撑使用时请留意各平台对refresher-default-style及 bool 属性书写的差异前文已给出 Android 与 Web 的注意事项。仓库示例与测试在哪里看完整可运行代码本仓库提供了可直接运行的对照资源组件源码src/uni_modules/uni-refresh-box/components/uni-refresh-box/uni-refresh-box.vue含完整 Props、状态机、插槽与内置样式组件 readmesrc/uni_modules/uni-refresh-box/readme.md滚动容器 refresher 属性演示src/pages/component/scroll-view/scroll-view-refresher-props.uvue自定义下拉刷新综合示例list-view refresh-boxsrc/pages/template/custom-refresher/custom-refresher.uvue下拉刷新相关测试scroll-view-refresher.test.js、list-view-refresh.test.js。常见问题与注意事项组件不显示检查滚动容器是否设置了refresher-enabledtrue且refresher-default-stylenoneslotrefresher是否书写在组件外层标签上。文案切换不同步确认滚动容器refresher-threshold与组件threshold取值一致否则组件会在容器触发刷新前后提前/滞后切换状态。Android 属性简写问题bool 属性需显式绑定refresher-enabled不可简写。归位瞬间文字闪烁状态 4归位中设计上不显示文字若出现异常闪烁检查refresherrestore/refresherabort是否将 pullingDistance 归零以及refreshing是否在复位前被正确置回 false。默认 loading 不转默认 loading 仅在currentState 2刷新中时旋转这是正常行为下拉过程中的转动由组件依据 pullingDistance 自行驱动旋转角度实现。掌握了状态机、属性语义与插槽机制之后你可以在任意滚动容器上快速搭建出与产品风格一致的自定义下拉刷新从“改文案”“改样式”到“完全重绘”全部无需依赖平台原生实现。赞分享示例工程前端移动开发跨平台【免费下载链接】uni-appA cross-platform framework using Vue.js项目地址https://gitcode.com/gh_mirrors/un/uni-app点击查看免费下载相关推荐uni-refresh-boxuni-app x 自定义下拉刷新组件原理与实战指南uni refresh boxuni app x 自定义下拉刷新组件原理与实战指南 uni refresh box 是 uni app x本仓库 src/u示例工程前端移动开发跨平台uni-app x 自定义 tab-bar 组件实战uni-tab 组件组完整使用指南uni app x 自定义 tab bar 组件实战uni tab 组件组完整使用指南 导读 本文讲解 uni app x含 Web / 微信小程序 / A示例工程前端移动开发跨平台uni-app x 自定义 TabBar 内容容器 uni-tab-content 组件完全指南uni app x 自定义 TabBar 内容容器 uni tab content 组件完全指南 uni tab content 是 uni app xuni示例工程前端移动开发跨平台上一篇GitHub_Trending/mu/MusicBot依赖版本管理范围与精确版本下一篇Scrapy-Redis队列系统详解3种队列类型及其适用场景创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考