ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Vant 4 CountDown 倒计时组件完全指南:从毫秒级渲染到实例方法控制

Vant 4 CountDown 倒计时组件完全指南:从毫秒级渲染到实例方法控制 Vant 4 CountDown 倒计时组件完全指南从毫秒级渲染到实例方法控制【免费下载链接】vantA lightweight, customizable Vue UI library for mobile web apps.项目地址: https://gitcode.com/GitHub_Trending/va/vantCountDown 是 Vant 4 移动端组件库中用于实时展示倒计时数值的组件支持毫秒级精度与自定义时间格式。本文将以 CountDown 官方文档 为主线结合组件源码、vant/use中useCountDown的底层实现与测试用例系统讲解倒计时的引入、五种典型用法、完整 API 与主题定制方案帮助你在秒杀、活动开售、验证码重发、答题限时等移动端场景中快速落地可靠的倒计时能力。组件能力概览与引入方式CountDown 组件定位轻量核心源码仅由一个 CountDown.tsx 渲染组件与一个 utils.ts 格式化工具组成全部时间计算逻辑下沉到独立的组合式函数useCountDown组件层保持高度精简。通过以下方式即可全局注册组件更多注册方式如局部注册、按需引入可参考 组件注册指南import { createApp } from vue; import { CountDown } from vant; const app createApp(); app.use(CountDown);注册后即可在模板中使用van-count-down标签。同时index.ts 中声明了VanCountDown的全局组件类型配合 Volar 可在模板中获得完整的类型提示与属性校验。基础用法以time为核心time属性表示倒计时总时长单位为毫秒。下面的示例创建了一个 30 小时的倒计时van-count-down :timetime /import { ref } from vue; export default { setup() { const time ref(30 * 60 * 60 * 1000); return { time }; }, };组件在挂载时即通过watch(() props.time, resetTime, { immediate: true })监听time的变化CountDown.tsx 中一旦time属性变化就会重置剩余时间若auto-start为true则重置后自动开始。因此动态修改time即可实现重置为新的时长的常见需求。需要说明的是组件根节点渲染了roletimer无障碍属性方便屏幕阅读器识别倒计时区域。自定义格式format 的解析规则通过format属性可以完全控制倒计时文本的内容例如van-count-down :timetime formatDD 天 HH 时 mm 分 ss 秒 /format支持以下占位符各占位符都会被零填充如05格式说明DD天数HH小时mm分钟ss秒数S毫秒1 位SS毫秒2 位SSS毫秒3 位默认值为HH:mm:ss。这里有两个值得留意的行为毫秒占位符按从长到短的顺序匹配先匹配SSS再匹配SS最后匹配单个S取毫秒值的前 1 或前 2 位展示当 format 中省略了某个高位单位时该单位会被折算进下一个单位。这一逻辑实现在 utils.ts 的parseFormat中if (format.includes(DD)) { format format.replace(DD, padZero(days)); } else { hours days * 24; // 未使用 DD 时天数折算进小时 } // HH / mm / ss 同理逐级折算也就是说若 format 不含DD小时会包含天数 × 24若不含HH分钟会折算 小时 × 60若不含mm秒数会折算 分钟 × 60若不含ss则毫秒会包含 秒 × 1000。这一规则保证了任何省略写法下总时长都不会丢失测试用例should format incomplete time correctlytest/index.spec.tsx专门验证了省略天数的折算行为。毫秒级渲染microTick 与 macroTick 的分工倒计时默认每秒渲染一次开启millisecond属性后即切换为毫秒级渲染van-count-down millisecond :timetime formatHH:mm:ss:SS /两种渲染模式由useCountDown内部的tick决定packages/vant-use/src/useCountDown/index.ts毫秒模式调用microTick每个requestAnimationFrame回调中都重新计算剩余时间并更新视图保证毫秒位实时跳动秒级模式调用macroTick利用isSameSecond判断秒数是否变化同一秒内不触发重复渲染大幅降低无效渲染开销。同时tick中通过inBrowser判断在服务端SSR环境下不启动计时避免水合不一致的问题。两种模式均以endTime Date.now() remain.value为基准计算Math.max(endTime - Date.now(), 0)得出剩余时间因此即便requestAnimationFrame被节流最终时间也不会漂移比逐帧递减remain更准确。自定义样式插槽与 timeData通过默认插槽可以完全自定义倒计时的外观插槽参数timeData即CurrentTime对象字段含义见下文 API 表格van-count-down :timetime template #defaulttimeData span classblock{{ timeData.hours }}/span span classcolon:/span span classblock{{ timeData.minutes }}/span span classcolon:/span span classblock{{ timeData.seconds }}/span /template /van-count-down style .colon { display: inline-block; margin: 0 4px; color: #1989fa; } .block { display: inline-block; width: 22px; color: #fff; font-size: 12px; text-align: center; background-color: #1989fa; } /style从 CountDown.tsx 可以看到渲染逻辑为存在默认插槽时优先渲染插槽内容传入current.value否则渲染parseFormat格式化后的纯文本。因此插槽方案与 format 方案二选一插槽方案适合将数字渲染为色块、胶囊、图片等富样式。仓库中的官方示例 demo/index.vue 还在此基础上加入了圆角与主题色变量可作为参考。手动控制start / pause / reset通过 ref 获取组件实例后可以调用start、pause、reset三个实例方法实现按钮驱动的倒计时van-count-down refcountDown millisecond :time3000 :auto-startfalse formatss:SSS finishonFinish / van-grid clickable van-grid-item text开始 iconplay-circle-o clickstart / van-grid-item text暂停 iconpause-circle-o clickpause / van-grid-item text重置 iconreplay clickreset / /van-gridimport { showToast } from vant; export default { setup() { const countDown ref(null); const start () { countDown.value.start(); }; const pause () { countDown.value.pause(); }; const reset () { countDown.value.reset(); }; const onFinish () showToast(倒计时结束); return { start, pause, reset, onFinish, countDown, }; }, };三个方法的行为与底层实现对应如下详见 packages/vant-use/src/useCountDown/index.ts方法名说明参数返回值start开始倒计时以当前剩余时间重新锚定endTime已结束时调用则从 0 继续--pause暂停倒计时取消当前rafId并保持剩余时间--reset重设倒计时为time属性值若auto-start为true重设后会自动开始--组件通过useExposepackages/vant/src/composables/use-expose.ts将这三个方法挂载到组件实例的 proxy 上因此模板中refcountDown拿到的实例可以直接调用。测试用例对上述三种操作均做了覆盖should start counting after calling the start method、should pause counting after calling the pause method、should reset time after calling the reset method见 test/index.spec.tsx。另外useCountDown还通过onActivated/onDeactivated钩子与KeepAlive协同组件被缓存停用时自动暂停、重新激活时自动续跑测试用例should pause counting when deactivated验证了该行为在列表页与详情页间切换的场景下可避免倒计时被错误推进。API 参考Props参数说明类型默认值time倒计时时长单位毫秒number | string0format时间格式stringHH:mm:ssauto-start是否自动开始倒计时booleantruemillisecond是否开启毫秒级渲染booleanfalsetime在 CountDown.tsx 中通过makeNumericProp(0)声明因此字符串类型的数字也会被正确转换为number后传入useCountDown。Events事件名说明回调参数finish倒计时结束时触发-change倒计时变化时触发currentTime: CurrentTimefinish与change分别由useCountDown的onFinish、onChange回调转发。setRemain中当剩余时间为 0 时会自动pause并触发finishchange则在每次剩余时间更新时触发回调参数为完整的CurrentTime对象测试用例should emit change event when counting验证了其参数结构。Slots名称说明参数default自定义内容currentTime: CurrentTimeCurrentTime 格式名称说明类型total剩余总时间单位毫秒numberdays剩余天数numberhours剩余小时numberminutes剩余分钟numberseconds剩余秒数numbermilliseconds剩余毫秒number该对象由 packages/vant-use/src/useCountDown/index.ts 的parseTime基于DAY / HOUR / MINUTE / SECOND常量逐级取整生成total始终等于原始剩余毫秒数。类型定义组件导出以下类型定义便于在 TypeScript 项目中获得强类型支持import type { CountDownProps, CountDownInstance, CountDownCurrentTime, } from vant;CountDownInstance是组件实例的类型用法如下import { ref } from vue; import type { CountDownInstance } from vant; const countDownRef refCountDownInstance(); countDownRef.value?.start();从 types.ts 可以看到CountDownInstance基于ComponentPublicInstanceCountDownProps, CountDownExpose构造其中CountDownExpose定义了start、pause、reset三个实例方法的签名CountDownCurrentTime则直接复用vant/use的CurrentTime类型。TS 环境下建议将 demo 中的ref(null)写法替换为refCountDownInstance()以获得方法调用时的完整提示。主题定制组件通过 index.less 提供了三个 CSS 变量可在根节点或通过 ConfigProvider 组件 统一覆盖实现与业务主题色的联动名称默认值描述--van-count-down-text-colorvar(--van-text-color)文本颜色--van-count-down-font-sizevar(--van-font-size-md)字号--van-count-down-line-heightvar(--van-line-height-md)行高这三个变量默认值均引用 Vant 全局基础变量因此在不做任何配置时倒计时文本会自动跟随主题风格自定义时只需在组件外层覆盖同名变量即可例如配合插槽方案渲染的彩色数字块时可同步调整字号与行高保证数字块间距统一。常见问题在 iOS 系统上倒计时不生效如果你遇到了在 iOS 上倒计时不生效的问题请确认在创建 Date 对象时没有使用new Date(2020-01-01)这样的写法。iOS 的 JavaScript 引擎不支持以中划线-分隔的日期字符串格式解析会得到Invalid Date进而导致所有时间计算返回NaN正确写法是使用斜杠分隔的new Date(2020/01/01)或将日期拆分为参数形式new Date(2020, 0, 1)。由于 CountDown 内部以Date.now()作为计时基准若业务侧传入的结束时间先经过错误的 Date 解析就会表现为倒计时不生效排查时可优先检查结束时间的构造方式。若需要基于某个未来时间点而非时长运行倒计时可先计算endTime.getTime() - Date.now()得到毫秒差再作为time传入组件同时注意遵循上述 iOS 兼容的日期构造写法。【免费下载链接】vantA lightweight, customizable Vue UI library for mobile web apps.项目地址: https://gitcode.com/GitHub_Trending/va/vant创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表