更新记录

1.0.0(2026-11-08) 下载此版本

  • 首个版本,按 uni_modules 规范发布:uni_modules/czh-mescroll,支持插件市场一键导入与从市场更新
  • 组件标签为 <czh-mescroll>,easycom 自动扫描,页面里不需要 import 或注册
  • 定高 scroll-view + 原生下拉刷新,触底加载;分页控制器通过 setLoader 注册,业务侧只需写一个异步加载函数
  • 自动收尾:loader 抛错或漏调 end* 时按 endErr 结束,底部进入「加载失败,点击重试」,不会卡在加载中
  • 内置空态、加载中、加载失败重试、返回顶部;首屏失败与失败页重试可点击
  • 空态图与返回顶部图随插件分发(static/img),组件内以 /uni_modules/czh-mescroll/static/img/... 引用,导入即用
  • emptyIcon / toTop.src 支持传空串隐藏、传 URL 覆盖内置图

平台兼容性

uni-app x(4.71)

Chrome Safari Android iOS 鸿蒙 微信小程序
√ √ √ √ √ √

其他

多语言 暗黑模式 宽屏模式 蒸汽模式
× × × √

czh-mescroll 下拉刷新 / 上拉加载(uni-app x)

针对 uni-app x vapor 编写的 mescroll 重实现:定高 scroll-view + 原生下拉刷新, 分页控制器用 setLoader 注册式接入,自带空态、加载中、加载失败重试与返回顶部。 不依赖旧版 mescroll 的 mixin / WXS / renderjs。

安装

已按 uni_modules 规范发布,二选一:

  • 插件市场:插件详情页点「使用 HBuilderX 导入插件」,选择目标项目,导入后自动落在 uni_modules/czh-mescroll;
  • 手动:把 uni_modules/czh-mescroll 整个目录复制到项目根目录的 uni_modules 下。
uni_modules/czh-mescroll/
├─ package.json
├─ readme.md
├─ changelog.md
├─ components/czh-mescroll/
│  ├─ czh-mescroll.uvue                业务封装(<czh-mescroll>)
│  └─ mescroll-uni/
│     ├─ mescroll-uni.uvue             定高 scroll-view 内核
│     ├─ mescroll-core.uts             分页控制器与类型
│     └─ components/*.uvue             空态 / 加载中 / 返回顶部
└─ static/img/                         内置空态图与返回顶部图

页面里直接写 <czh-mescroll> 即可(easycom 自动扫描 uni_modules/*/components/组件名/组件名.uvue,标签名 = 组件目录名), 不需要 import、也不需要注册。

仅支持 uni-app x(uvue),不支持 uni-app(vue2/vue3)。

结构

  • components/czh-mescroll/czh-mescroll.uvue:业务封装,支持多 tab 懒加载、默认插槽及原 mescrollSlot 命名插槽。
  • components/czh-mescroll/mescroll-uni/mescroll-uni.uvue:定高 scroll-view,管理原生下拉刷新、触底加载和滚动。
  • components/czh-mescroll/mescroll-uni/mescroll-core.uts:分页控制器和公开类型。
  • components/czh-mescroll/mescroll-uni/components/*.uvue:空状态、加载状态及返回顶部组件。
  • static/img/nodata.png、static/img/icon_to_top.png:空态图与返回顶部图,组件内以 /uni_modules/czh-mescroll/static/img/... 引用,导入即用,不需要往项目 static 里拷图。
  • 接入示例:本示例工程 pages/index/index.uvue(模拟数据,演示多 tab 懒加载、下拉刷新、 触底加载、首屏失败重试、失败页重试、接口不返回 count、空态与返回顶部)。

小程序端的组件注册

微信小程序要求自定义组件出现在页面 usingComponents 里才会被创建;App / Web / 鸿蒙走 VDOM 不需要。 用 easycom 标签 <czh-mescroll>(或显式 import 该 .uvue)后,编译器会自动把组件写进页面 json,不需要再手动注册一次。

不要在 pages.json 的 globalStyle 里再补一条根路径的全局注册:

"usingComponents": { "czh-mescroll": "/uni_modules/czh-mescroll/components/czh-mescroll/czh-mescroll" }

同一个组件会因此同时以「@/ 别名导入」和「根路径」两个模块 id 进入打包。编译器只能把它提成共享 chunk, 产物里组件目录只剩 .wxml / .json 而没有 .js,微信端报 Component is not found in path "…/mescroll"。

还有一类更隐蔽的原因:组件之间循环依赖。若某个 .uvue 只 import { type X } from './xxx.uts', uts 的 type 导入会被编译成运行时依赖,令它与 xxx.uvue 互相依赖;小程序端遇到这种环会把组件提成异步 chunk (页面 js 里出现 const Mescroll = () => "../../<base64>.js".then(...)),组件自己的 .js 就不生成了。 本插件的 czh-mescroll.uvue 因此改成在本地声明类型、不从 mescroll-core.uts 引入 —— 改这几行类型时记得两边同步。

判据:unpackage/dist/dev/mp-weixin/<组件路径>/ 下缺 .js,同时 dist 根目录多出一个 base64 命名的 .js (解码后正是该 .uvue 的绝对路径)。遇到它,删掉重复的注册、清掉 unpackage/dist/dev/mp-weixin 重新运行即可。

另外 height 必须是正数:组件内是 v-if,算不出高度(窗口信息缺失、safeArea 为空等)时整块不会渲染, 表现同样是「列表空白 + 接口不请求」。取高度的函数要兜底一个可用值,不要直接把 safeArea.height 或 windowHeight 的裸运算结果赋给 height,示例页 calcHeight() 就是带兜底的写法。

业务封装

直接用 easycom 标签 <czh-mescroll> 即可,不需要 import。

属性 默认值 说明
height 0 滚动容器高度,单位 px;大于 0 才挂载
i / index 0 / 0 当前实例下标 / 激活下标,首次激活时请求第一页
size 20 每页大小,用于回调里的 page.size 及 endSuccess 的默认结束判断;不会自动发给服务端,按自己接口取用即可(示例页传 10)
downUse / isLock true / false 开启下拉 / 锁定下拉
textColor / bgColor #999999 / #ffffff 底部文字及背景、刷新背景
showToTop true 显示返回顶部按钮(圆形,距底 60rpx),使用插件内置图片,可用 toTop.src 覆盖
noMoreSize 1 达到此列表总数才显示结束文字
textNoMore 没有更多数据了~ 结束文字,空串隐藏
textLoading 加载中... 加载中提示文字
emptyUse / emptyIcon / emptyTip true / 内置图 / 暂无数据~ 内置空状态开关、图片与文字;emptyIcon 传空串隐藏图片,传 URL 覆盖内置图

内置空状态样式与项目通用 empty-list 组件一致;首屏(列表尚无任何数据时)的加载中与加载失败显示为更高的居中提示,加载更多时为常规小字条。

@init 返回 MescrollInstance,分页加载函数必须在 init 时用 setLoader 注册(对应原版 mescroll 直接给 upCallback 传 async 函数的用法):

const initMescroll = (instance: MescrollInstance) => {
    instance.setLoader(async (page: MescrollPage) => {
        // 以典型后端接口为例(示例工程 pages/index/index.uvue 用模拟数据演示了全部场景)
        const res = await getXxxList({ p: page.num }) as MyResponse<XxxInfo[]>
        if (!instance.isRequestCurrent(page.requestId)) return // 旧响应不再写回列表
        if (res.status != '1' && res.status != 1) return // 失败路径由组件兜底结束
        const list = res.info ?? []
        listData.value = page.num == 1 ? list : listData.value.concat(list)
        instance.endBySize(list.length, res.count ?? null, page.requestId)
    })
}

loader 模式下业务不需要 try/catch:加载函数抛错、或正常结束但未调用任何 end* 方法时,控制器都会自动按 endErr 收尾,底部进入“加载失败,点击重试”,不会卡在加载中(原版 mescroll 只有抛错自动结束,漏调 end* 会一直转圈)。 业务 status 失败时直接 return 即可;成功后第一页替换列表、其余页追加,调用 endBySize(本页条数, res.count ?? null, page.requestId) 一行收尾:总数存在时按累计条数精确判断下一页,count 缺失时按项目约定自动视为无更多数据。仅当需要完全自定义"是否还有下一页"(比如按"不满一页即停"推断)时才用 endSuccess(本页条数, 是否有下一页, page.requestId)。 写回列表前的 isRequestCurrent(page.requestId) 建议保留:下拉刷新会发起新请求,旧响应返回时应直接丢弃,防止写坏新列表。

@down-callback 为下拉通知,组件会自动重置并触发加载,不必重复发请求。 @scroll 返回控制器,滚动位置从 instance.state.scrollTop 读取。 需要保留控制器引用时保存为普通变量即可,不要塞进 ref/reactive。

控制器

  • setLoader(loader):注册异步分页加载函数(推荐接入方式);其抛错或漏调 end* 时自动按 endErr 收尾。
  • resetUpScroll(false):静默请求第一页,可替代正在进行的请求,不自动清空业务数组。
  • resetUpScroll(true):请求第一页并显示刷新动画。
  • resetUpScroll(showLoading, true):请求第一页并回到顶部;筛选、搜索词变化后重置列表时使用,静默刷新保持原滚动位置。
  • triggerDownScroll():触发下拉通知和第一页请求,遵守下拉锁定状态。
  • triggerUpScroll():加载下一页,防重复加载;无更多数据时不再请求。
  • endBySize(本页条数, 总数):结束本次请求并计算分页状态;总数直接传 res.count ?? null,为 null(接口未返回 count)时自动视为无更多数据。
  • endByPage / endSuccess:结束本次请求并计算分页状态;endSuccess 用于完全自定义是否还有下一页。
  • endErr:结束本次请求、保留旧列表及已成功页码,记录失败页供重试。
  • clear():使旧请求失效并清空分页状态;业务列表由调用者清空。
  • lockDownScroll / lockUpScroll:动态锁定刷新或加载。
  • scrollTo(top, duration):滚动到 px 位置;duration 为 0 时无动画,否则使用平台默认动画。
  • endDownScroll():仅关闭刷新动画,不结束分页请求。

异步完成方法的最后一个 requestId 参数可省略,但涉及重置、筛选或切换科目时应始终传入。 组件卸载会自动使未完成请求失效。

直接使用底层组件

显式导入 @/uni_modules/czh-mescroll/components/czh-mescroll/mescroll-uni/mescroll-uni.uvue,使用 height="400px" 或已定高父容器内的 height="100%"。 支持 down、up 类型化选项,事件为 init、down、scroll、topclick;分页加载函数同样在 init 时通过 setLoader 注册。 完整选项见 MescrollDownOption / MescrollUpOption 类型定义。 在 @down 内同步调用 resetUpScroll 也可兼容原调用方式,控制器不会重复发起默认请求。

迁移边界

这不是原版全部选项的逐项兼容层。下拉头使用 scroll-view 原生刷新样式,不再使用 WXS/renderjs 自定义拖拽。 不迁移 mescroll-body 页面滚动及原版 mixin;本项目页面内的滚动统一使用定高组件。 不提供原 fixed/top/bottom/topbar/bottombar 自动布局,由业务容器明确计算高度。 up.page.num 保留类型兼容,但本实现始终从第一页开始,不支持从中间页初始化。 短列表仍有下一页时提供“点击加载更多”入口,避免内容不足一屏无法触底。 返回顶部位于组件右下角,bottom/right 选项单位为 rpx,不使用全屏 fixed。 count 缺失时结束分页的项目约定已内置于 endBySize(总数传 null 即触发);总数存在时按实际累计条数判断,不依赖固定 pageSize。

隐私、权限声明

1. 本插件需要申请的系统权限列表:

无

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

无

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

无

许可协议

MIT协议

暂无用户评论。