前端UI组件移动开发小程序【免费下载链接】wot-design-uni一个基于Vue3TS开发的uni-app组件库提供70高质量组件支持暗黑模式、国际化和自定义主题。项目地址https://gitcode.com/gh_mirrors/wo/wot-design-uni点击查看免费下载wd-resize是 wot-design-uni 组件库中专门用于监听元素尺寸变化的容器组件当组件包裹的文档流尺寸发生变化时它会触发resize事件并携带元素最新的宽高与位置信息。本文以官方文档 resize.md 为核心结合仓库内组件源码、样式文件与单元测试系统讲解wd-resize的用法、参数、事件、底层实现原理及其在wd-sticky、wd-sticky-box中的真实应用场景。组件定位与适用场景在 uni-app 小程序与 H5 环境中DOM 的尺寸变化并不总能被可靠的resize事件感知。当页面内容因为异步数据返回、图片加载、插值渲染等原因更新后元素的宽高和位置往往随之改变此时如果需要重新计算布局例如重算吸顶位置、重新定位浮层、重排表格列宽就必须主动重新获取元素的尺寸与位置。wd-resize正是为了解决这一痛点而设计它作为包裹容器持续监听被包裹内容default插槽的文档流尺寸变化一旦发生变化便触发resize事件并将width、height、top、right、bottom、left六个维度的最新值一次性回传给业务代码方便开发者重新执行内容展示相关的计算操作。从源码结构看该组件实现非常轻量完整代码位于 wd-resize.vue类型声明在 types.ts样式在 index.scss并在 global.d.ts 中注册为全局组件WdResize。基本用法使用wd-resize非常简单将需要监听尺寸变化的内容放入默认插槽并监听resize事件即可。注意不要给此组件增加任何外部样式以免破坏其内部的文档流测量机制具体原因见下文底层实现原理一节。以下示例演示了当插槽内视图的宽高从默认状态变为100px × 100px时组件自动感知并触发回调的完整流程wd-resize resizehandleResize view :stylebackground: #4d80f0; width: ${width};height: ${height}/view /wd-resizeconst width refstring() const height refstring() onReady(() { setTimeout(() { width.value 100px height.value 100px }, 1500) }) function handleResize(detail: Recordstring, string | number) { const { height, width, top, right, bottom, left } detail console.log(height, width, top, right, bottom, left) }示例的运行逻辑为页面onReady后 1.5 秒将width与height置为100px插槽内容尺寸发生改变wd-resize检测到变化并触发handleResize此时可在控制台看到元素最新的宽高与四边位置信息。这一用例在仓库中也有完整的可运行演示页面位于 src/subPages/resize/Index.vue页面实时展示上一次与当前两次回调中的width、height、top、right、bottom、left对比值可直接运行 uni-app 项目查看效果。更完整的实战模板将事件回调的参数保存到响应式变量中即可驱动后续布局计算script langts setup import { ref } from vue import { onReady } from dcloudio/uni-app const contentWidth refstring() const contentHeight refstring() const size ref({ width: 0, height: 0, top: 0, right: 0, bottom: 0, left: 0 }) onReady(() { // 模拟异步内容加载导致尺寸变化 setTimeout(() { contentWidth.value 200px contentHeight.value 120px }, 500) }) function handleResize(detail: Recordstring, string | number) { size.value { width: Number(detail.width), height: Number(detail.height), top: Number(detail.top), right: Number(detail.right), bottom: Number(detail.bottom), left: Number(detail.left) } // 在这里重新执行位置/布局计算 } /scriptAttributes 参数说明wd-resize的参数非常精简官方文档定义了三个属性参数说明类型可选值默认值最低版本custom-style自定义根节点样式string---custom-class自定义根节点样式类string---custom-container-class自定义容器样式类string---对照源码 types.ts 可以发现其具体定义方式import { baseProps, makeStringProp } from ../common/props export const resizeProps { ...baseProps, customContainerClass: makeStringProp() }三个属性的来源与含义如下custom-style / custom-class由公共的 baseProps 提供通过makeStringProp()声明为默认值为空字符串的String类型 prop。分别用于向组件根节点.wd-resize追加内联样式与样式类。在 wd-resize.vue 中根节点被渲染为view :classwd-resize ${customClass} :stylerootStyle其中rootStyle由计算属性拼接组件内部的宽高值再合并customStyle得到const rootStyle computed(() { const style: Recordstring, string | number { width: addUnit(width.value), height: addUnit(height.value) } return ${objToStyle(style)}${props.customStyle} })也就是说组件会自动将测量到的宽高写入根节点保证父容器不会因插槽尺寸变化而坍塌custom-style在此基础上继续追加业务自定义样式。custom-container-class为内部测量容器.wd-resize__container追加样式类由makeStringProp()声明。该容器在模板中渲染为view :idresizeId :classwd-resize__container ${customContainerClass}它是真正承载插槽内容与两个监听scroll-view的结构。Events 事件说明事件名称说明参数最低版本resize尺寸发生变化时触发{width: number, height: number, top: number, right: number, bottom: number, left: number}-resize事件在两种情况下触发首次检测到尺寸变化时组件挂载后的第一次滚动事件回调之后每次宽高真正发生变化时通过新旧值对比确认。从源码 wd-resize.vue 可以看到事件载荷通过uni.createSelectorQuery().in(proxy).select(...).boundingClientRect()获取字段按固定顺序提取;[bottom, top, left, right, height, width].forEach((propName) { result[propName] res[propName] }) emit(resize, result)因此回调中拿到的width、height为元素实际渲染尺寸单位 pxtop、right、bottom、left为元素相对视口viewport的四边位置坐标可用于计算元素占位区域或判断是否进入可视范围。一个值得注意的实现细节是当宽高同时变化时只触发一次resize事件。源码中通过emitStack数组对newHeight ! lastHeight与newWidth ! lastWidth分别判断只要任一维度发生变化即合并为一次事件发出避免业务回调被重复触发const emitStack: number[] [] if (newHeight ! lastHeight) { lastHeight newHeight emitStack.push(1) } if (newWidth ! lastWidth) { lastWidth newWidth emitStack.push(1) } if (emitStack.length ! 0) { // 组装结果并 emit(resize, result) }Slots 插槽插槽名称说明最低版本default需要监听尺寸变化的内容-default插槽是组件唯一提供的插槽用于放置需要被监听尺寸变化的内容。组件模板将其直接放入测量容器中wd-resize.vueview :idresizeId :classwd-resize__container ${customContainerClass} !--被监听的插槽-- slot / !--监听插槽变大-- scroll-view ... / !--监听插槽变小-- scroll-view ... / /view插槽内容与两个监听用scroll-view同处于容器内便于统一测量尺寸。底层实现原理基于双 scroll-view 的尺寸监听在小程序环境中并没有 Web 端的ResizeObserverAPIwd-resize采用了经典的滚动条触发方案来跨端实现尺寸监听。其核心思路在源码注释与模板结构中有清晰体现wd-resize.vue第一步让插槽脱离父容器文档流。内部容器.wd-resize__container在 index.scss 中被设置为position: absolute目的如源码注释所述插槽需要脱离父容器文档流防止父容器固宽固高进而导致插槽大小被父容器限制。这样插槽的尺寸由其自身内容决定变化时才能被准确感知。第二步埋入两个隐藏的 scroll-view 作为探针。监听插槽变大第一个scroll-view内放置一个height: 100000px; width: 100000px的占位元素并将其scroll-top/scroll-left设置到接近底部的超大值。当插槽变大、容器随之变高变宽时滚动条的可滚动距离变大滚动位置被迫回弹从而触发scroll事件。监听插槽变小第二个scroll-view内放置一个height: 250%; width: 250%的占位元素。当插槽缩小时可滚动距离变小同样会触发滚动事件。两个探针统一绑定scrollonScrollHandler通过滚动事件间接感知容器尺寸的任何变化。同时index.scss 将.wd-resize__wrapper设置为position: absolute; top/bottom/left/right: 0; z-index: -9999; overflow: hidden; visibility: hidden让探针完全不可见、不干扰页面布局。第三步滚动回调中重新测量并防抖。onScrollHandler内重新执行boundingClientRect查询并通过scrollEventCount计数器做了两层过滤wd-resize.vueonScrollHandler () { const query uni.createSelectorQuery().in(proxy).select(#${resizeId.value}).boundingClientRect() query.exec(([res]) { // 前两次滚动事件被触发说明 created 的修改已渲染通知用户代码当前容器大小 if (scrollEventCount.value 0) { const result: Recordstring, string | number {} ;[bottom, top, left, right, height, width].forEach((propName) { result[propName] res[propName] }) emit(resize, result) } // 滚动条拉到底部会触发两次多余的事件屏蔽掉。 if (scrollEventCount.value 3) return // ... }) }首次滚动事件用于在渲染完成后立即上报一次初始尺寸随后两次由滚动条拉到底部产生的冗余事件被屏蔽从第三次起才进行真正的尺寸对比与事件分发。每次回调结束后通过scrollToBottom将滚动位置重新拉回底部为下一次变化做准备function scrollToBottom({ lastWidth, lastHeight }: { lastWidth: number; lastHeight: number }) { expandScrollTop.value 100000 lastHeight shrinkScrollTop.value 3 * height.value lastHeight expandScrollLeft.value 100000 lastWidth shrinkScrollLeft.value 3 * width.value lastWidth }第四步父容器防坍塌。测量到新尺寸后组件立即将width/height写入根节点的内联样式即rootStyle计算属性保证外层父容器始终跟随内容尺寸避免因插槽尺寸变化导致布局跳动或父容器高度塌陷。此外组件的容器id通过uuid()动态生成resize${uuid()}uuid实现见 util.ts确保同一页面内多个wd-resize实例互不冲突选择器查询使用.in(proxy)限定在当前组件实例作用域内避免跨组件误选。组件内部复用wd-sticky 与 wd-sticky-boxwd-resize并非孤立组件它被 wot-design-uni 内部多个需要实时感知尺寸的组件复用这从侧面印证了其设计价值wd-sticky.vue 中吸顶容器通过wd-resize resizehandleResize custom-styledisplay: inline-block;包裹插槽利用 resize 回调中返回的top、height等值实时计算吸顶偏移量wd-sticky-box.vue 同样用wd-resize包裹默认插槽在handleResize中记录内容尺寸以撑开占位区域。由此可见凡是内容尺寸不确定、又需要据此做布局计算的场景吸顶、吸底、定位浮层、动态列表撑位等都可以借鉴这种外层包一个wd-resize的用法。单元测试验证仓库为wd-resize提供了完整的单元测试 tests/components/wd-resize.test.ts覆盖以下行为基本渲染挂载后根节点包含wd-resize类名自定义类名传入custom-class后根节点追加对应类名自定义样式传入custom-style后根节点内联样式包含传入内容自定义容器类名传入custom-container-class后.wd-resize__container容器追加对应类名默认插槽插槽内容被正确渲染resize 事件模拟调用onScrollHandler后组件成功emit(resize)。这些测试用例与 types.ts、wd-resize.vue 的实现一一对应可作为理解组件行为契约的补充资料。最佳实践小结不要给wd-resize增加外部样式组件依赖绝对定位的内部容器与隐藏滚动探针完成测量外部样式可能破坏其文档流模型导致监听失效尺寸变化驱动计算将resize回调返回的六元组数据宽高 四边位置保存为响应式状态再驱动吸顶、定位、撑位等布局计算避免在业务层轮询测量宽高同时变化只触发一次回调天然具备合并去重能力无需在业务层做额外的防抖合并可安全复用组件支持同页面多实例动态id 实例作用域查询且被wd-sticky、wd-sticky-box等官方组件内部使用可直接用于自定义布局组件开发。赞分享前端UI组件移动开发小程序【免费下载链接】wot-design-uni一个基于Vue3TS开发的uni-app组件库提供70高质量组件支持暗黑模式、国际化和自定义主题。项目地址https://gitcode.com/gh_mirrors/wo/wot-design-uni点击查看免费下载相关推荐如何利用Super Productivity的Resize Observer实现响应式任务管理界面如何利用Super Productivity的Resize Observer实现响应式任务管理界面 Super Productivity是一款集成了时间盒管理和前端桌面应用移动开发You-Dont-Need-jQuery中的Resize Observer元素尺寸变化监听You Dont Need jQuery中的Resize Observer元素尺寸变化监听 你是否还在为网页元素尺寸变化监听而烦恼是否觉得使用jQuery实教程前端高性能元素尺寸监听器 —— element-resize-detector高性能元素尺寸监听器 —— element resize detector 当涉及到网页元素的实时尺寸变化监测时 element resize detecto上一篇Feathers 与 Koa 集成指南从 feathersjs/koa 的演进看 KoaJS 传输适配器的设计下一篇如何使用ProGuard压缩、优化和混淆Java应用从入门到精通创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考