
UI组件前端【免费下载链接】varletA Vue3 component library based on Material Design 2 and 3, supporting mobile and desktop.项目地址https://gitcode.com/gh_mirrors/va/varlet点击查看免费下载轮播Swipe是移动端组件库中最常用的交互组件之一用于在一组内容之间进行横向或纵向滑动切换。本文以 Varlet 组件库Vue3、Material Design 2/3内置的Swipe组件为对象围绕官方文档逐项展开先通过可复制的代码示例掌握基本使用、禁止循环、自动播放、垂直轮播、导航按钮、切换监听与自定义指示器再完整列出属性、方法、事件、插槽与样式变量 API最后深入组件源码剖析轨道平移、触摸拖拽、循环回绕与父子通信的实现原理帮助你既会用、又懂为什么这样实现。组件简介Swipe用于显示一组可以在屏幕上滑动切换的内容集合常见于 Banner 广告、图片画廊、公告轮播等场景。它由两个组件配合使用var-swipe轮播容器负责轨道位移、自动播放、触摸交互、指示器与导航按钮var-swipe-item单个轮播项承载具体内容。组件源码位于 swipe 目录 与 swipe-item 目录通过 index.ts 使用withInstall挂载为全局组件也可以按需引入。使用前请参照快速上手文档完成组件注册。基本使用最基础的用法是把多个var-swipe-item放进var-swipe每个轮播项内部放入任意内容。由于容器高度默认由内容撑开文档示例中显式给容器设置height: 160px图片使用object-fit: cover铺满并关闭指针事件避免图片默认行为干扰手势template var-swipe classswipe-example var-swipe-item img classswipe-example-image srccat.jpg /var-swipe-item var-swipe-item img classswipe-example-image srccat2.jpg /var-swipe-item var-swipe-item img classswipe-example-image srccat3.jpg /var-swipe-item /var-swipe /template style .swipe-example { height: 160px; } .swipe-example-image { width: 100%; height: 100%; object-fit: cover; pointer-events: none; } /style示例中的三张猫图对应仓库内置的演示资源 packages/varlet-ui/public 目录 下的cat.jpg、cat2.jpg、cat3.jpg实际开发时替换为业务图片即可。默认情况下轮播是循环的滑到末尾会回绕到开头默认显示第一项并自带底部圆点指示器可直接左右拖拽切换。核心功能配置禁止循环轮播轮播默认在首尾之间循环回绕loop默认true。当内容具有明确先后顺序、不应回绕时可通过:loopfalse关闭循环。关闭后滑动到第一项或最后一项即被卡住导航按钮在边界处也会自动禁用见下文导航一节template var-swipe classswipe-example :loopfalse var-swipe-item img classswipe-example-image srccat.jpg /var-swipe-item var-swipe-item img classswipe-example-image srccat2.jpg /var-swipe-item var-swipe-item img classswipe-example-image srccat3.jpg /var-swipe-item /var-swipe /template style .swipe-example { height: 160px; } .swipe-example-image { width: 100%; height: 100%; object-fit: cover; pointer-events: none; } /style在 Swipe.vue 中非循环模式通过clamp(index, 0, length - 1)将索引约束在合法区间内测试用例 index.spec.js 也验证了loop: false时在末项继续向左拖拽change事件不再触发。开启自动播放设置autoplay属性单位毫秒即可自动轮播。例如:autoplay2000表示每 2 秒切换一页template var-swipe classswipe-example :autoplay2000 var-swipe-item img classswipe-example-image srccat.jpg /var-swipe-item var-swipe-item img classswipe-example-image srccat2.jpg /var-swipe-item var-swipe-item img classswipe-example-image srccat3.jpg /var-swipe-item /var-swipe /template style .swipe-example { height: 160px; } .swipe-example-image { width: 100%; height: 100%; object-fit: cover; pointer-events: none; } /style从源码看自动播放并非使用setInterval而是在 Swipe.vue 中通过setTimeout递归调用next()实现每轮播一次重新排定下一次定时器因此天然支持在组件卸载、弹层关闭、用户开始触摸等时机优雅地停止stopAutoplay。同时当轮播项数量length 1时不会启动避免单页空转。垂直轮播通过vertical属性开启垂直方向的上下轮播指示器、导航按钮与手势方向都会自动切换为纵向布局template var-swipe classswipe-example vertical var-swipe-item img classswipe-example-image srccat.jpg /var-swipe-item var-swipe-item img classswipe-example-image srccat2.jpg /var-swipe-item var-swipe-item img classswipe-example-image srccat3.jpg /var-swipe-item /var-swipe /template style .swipe-example { height: 160px; } .swipe-example-image { width: 100%; height: 100%; object-fit: cover; pointer-events: none; } /style源码中vertical由computed派生并作为SwipeProvider的一部分向下传递SwipeItem.vue 据此决定自身宽高与translateYswipe.less 通过--vertical、--indicators-vertical、--navigation-vertical-*系列修饰类切换布局。导航按钮设置navigation可开启上一页/下一页按钮。当navigation为字符串hover时按钮仅在指针悬浮于轮播区域时显示桌面端适用并带有淡入滑出的过渡动画template var-swipe classswipe-example navigation var-swipe-item img classswipe-example-image srccat.jpg /var-swipe-item var-swipe-item img classswipe-example-image srccat2.jpg /var-swipe-item var-swipe-item img classswipe-example-image srccat3.jpg /var-swipe-item /var-swipe var-swipe classswipe-example navigationhover var-swipe-item img classswipe-example-image srccat.jpg /var-swipe-item var-swipe-item img classswipe-example-image srccat2.jpg /var-swipe-item var-swipe-item img classswipe-example-image srccat3.jpg /var-swipe-item /var-swipe /template style .swipe-example { height: 160px; margin-top: 14px; } .swipe-example-image { width: 100%; height: 100%; object-fit: cover; pointer-events: none; } /style实现细节默认导航按钮基于var-button与var-icon组合渲染横向轮播使用chevron-left/chevron-right图标垂直轮播自动切换为chevron-up/chevron-downhovering状态由v-hover指令维护Swipe.vue 中的handleHovering仅在navigation hover时才更新悬浮状态非循环模式下第一页的“上一页”按钮与最后一页的“下一页”按钮会通过:disabled!loop index ...自动禁用导航按钮的入场/离场动画定义在 swipe.less 中水平与垂直方向各有独立的transition类。监听切换Swipe在切换发生时触发change事件回调参数为当前轮播项的索引从 0 开始。文档示例通过Snackbar即时提示当前索引script setup import { Snackbar } from varlet/ui /script template var-swipe classswipe-example change(index) Snackbar(String(index)) var-swipe-item img classswipe-example-image srccat.jpg /var-swipe-item var-swipe-item img classswipe-example-image srccat2.jpg /var-swipe-item var-swipe-item img classswipe-example-image srccat3.jpg /var-swipe-item /var-swipe /template style .swipe-example { height: 160px; } .swipe-example-image { width: 100%; height: 100%; object-fit: cover; pointer-events: none; } /style需要注意change仅在索引发生变化时触发。源码中prev/next会先比较新旧索引handleTouchend里也有if (prevIndex ! index.value)的守卫而to(idx)若目标索引与当前一致会直接return因此不会产生多余事件。测试用例 index.spec.js 中的swipe next prev to method用例完整验证了这一点to(0)时onChange调用次数仍为 0。自定义指示器默认指示器是一排小圆点通过indicator插槽可以完全自定义指示器的展示形式。插槽作用域提供index当前索引、length轮播总数、to跳转函数点击指示器可跳转到对应页等参数template var-swipe classswipe-example var-swipe-item img classswipe-example-image srccat.jpg /var-swipe-item var-swipe-item img classswipe-example-image srccat2.jpg /var-swipe-item var-swipe-item img classswipe-example-image srccat3.jpg /var-swipe-item template #indicator{ index, length, to } div classswipe-example-indicators div classswipe-example-indicator v-for(l, idx) in length :keyl :class{swipe-example-active-indicator: idx index} clickto(idx) /div /div /template /var-swipe /template style .swipe-example { height: 160px; } .swipe-example-image { width: 100%; height: 100%; object-fit: cover; pointer-events: none; } .swipe-example-indicators { position: absolute; display: flex; bottom: 10px; left: 50%; transform: translateX(-50%); } .swipe-example-indicator { width: 8px; height: 8px; background: #fff; opacity: 0.3; margin: 0 4px; transition: opacity 0.3s; } .swipe-example-active-indicator { opacity: 1; } /style默认指示器在源码中的渲染逻辑为indicator length时循环生成length个小圆点当前项通过--indicator-active修饰类提升不透明度0.3 - 1并支持点击跳转clickto(idx)垂直模式下指示器自动改为右侧纵向排列。默认圆点背景色由--swipe-indicator-color变量控制也可直接通过indicator-color属性覆盖。对应的官方演示还可在 example/index.vue 中查看。API 参考属性Props参数说明类型默认值loop是否开启循环轮播booleantrueautoplay自动播放间隔时间 (ms)string | number-duration切换过渡时间 (ms)string | number300initial-index初始化显示的索引string | number0indicator是否显示指示器booleantrueindicator-color指示器颜色string-vertical是否开启垂直轮播booleanfalsetouchable是否可以拖动booleantruenavigation是否显示导航箭头。设置为hover时指针悬浮会显示导航按钮boolean | stringfalse各属性的类型与默认值定义在 props.ts 中对应的 TypeScript 声明位于 swipe.d.ts。补充说明loop关闭后索引被约束在0 ~ length-1不会越界回绕duration控制transition-duration通过 inline style 写入轨道容器测试用例swipe duration验证了transition-duration: 500ms;的写入initial-index支持字符串或数字内部经toNumber转换后由clampIndex归一化如索引超出范围或为负数时循环取模indicator-color以 inlinebackground样式直接作用在圆点上touchable: false时触摸事件处理函数直接返回轮播退化为仅靠导航/API 切换测试用例touch touchable验证了touchable: false下拖拽不会触发change。方法Methods方法名说明参数返回值resize产生位置大小变化时可以调用此方法进行重绘--prev上一页options?: SwipeToOptions-next下一页options?: SwipeToOptions-to跳转到指定下标index: number, options?: SwipeToOptions-SwipeToOptions参数说明类型默认值event值为false时阻止触发change事件boolean-方法通过setup返回并暴露给模板引用可通过组件ref调用例如swipeRef.value.next()。源码实现要点next()/prev()先clampIndex得到新索引再根据options?.event ! false决定是否触发change循环模式下首尾衔接时还会借助fixPosition与setTranslate完成“无缝回绕”避免滑动中断感to(idx)会把目标索引裁剪到[0, length]范围然后按方向差异连续调用next/prev且只在最后一步透传options.event中间步骤一律传event: false保证一次跳转只触发一次changeresize()读取容器offsetWidth/offsetHeight重新计算轨道尺寸并通知所有轮播项与注册的 resize 监听器适合在容器尺寸变化如窗口缩放、弹层重新打开、路由切换时手动调用。事件Events事件名说明参数change切换轮播时触发index: number轮播索引插槽SlotsSwipe Slots插槽名说明参数default轮播内容-prev上一页按钮index: number轮播索引length: number轮播总数hovering: boolean指针是否悬浮to、prev、next: 类型和同名方法一致next下一页按钮index: number轮播索引length: number轮播总数hovering: boolean指针是否悬浮to、prev、next: 类型和同名方法一致indicator指示器内容index: number轮播索引length: number轮播总数hovering: boolean指针是否悬浮to、prev、next: 类型和同名方法一致SwipeItem Slots插槽名说明参数default轮播项内容-插槽作用域类型在 swipe.d.ts 中定义为SwipeIndicatorData含index、length、hovering、prev、next、to因此在自定义prev/next/indicator插槽时既可以使用插槽作用域里的方法跳页也可以据此实现任意形态的导航 UI。样式变量以下为组件使用的 CSS 变量可以使用 StyleProvider 组件 进行主题化定制变量名默认值--swipe-indicator-color#fff--swipe-indicators-offset10px--swipe-indicator-offset4px--swipe-navigation-z-index9--swipe-navigation-button-width36px--swipe-navigation-button-height36px--swipe-navigation-button-border-radius50%--swipe-navigation-icon-size20px--swipe-navigation-prev-left8px--swipe-navigation-next-right8px--swipe-navigation-prev-top8px--swipe-navigation-next-bottom8px这些变量的默认值统一声明在 swipe.less 的:root块中分别控制指示器颜色与间距、导航按钮的尺寸/圆角/图标大小以及水平/垂直两种布局下前后按钮的定位偏移。源码实现原理轨道平移机制Swipe的核心是一个“轨道track”容器横向轮播时容器宽度等于“单页宽度 × 页数”纵向时高度同理然后通过transform: translateX/translateY把当前页平移到可视区域。关键变量size单页尺寸横向取offsetWidth纵向取offsetHeighttrackSize size * length轨道总尺寸trackTranslate index * -size当前位移。对应的渲染逻辑在 Swipe.vue 的模板中transitionDuration由duration决定而lockDuration为true时过渡时间强制为0ms用于循环回绕时的“瞬移”衔接。触摸拖拽与方向判定触摸逻辑复用 varlet/use 的 useTouchtouchstart记录起点与时间touchmove累计deltaX/deltaY并判断手势方向比较两个方向偏移量得出horizontal或vertical。Swipe.vue 中通过isExpectDirection确保横向轮播只响应水平手势、纵向轮播只响应垂直手势方向不符直接忽略避免与页面滚动冲突方向正确时preventDefault阻止默认行为并实时累加trackTranslate。松手时依据“快速滑动”判定决定切换逻辑SWIPE_DELAY 250ms内完成且位移超过SWIPE_OFFSET 20px视为快速滑动直接跳到相邻页否则根据松手位置就近取整决定目标页。测试侧通过 utils/test.ts 的triggerDrag分四段触发touchmove来模拟真实拖拽过程。循环轮播的无缝回绕循环模式的难点在于首尾衔接。源码通过三步协作实现dispatchSwipeItems()拖拽过程中若轨道左/右越界提前把首尾两项平移到轨道外侧setTranslate(±trackSize)让首尾页在视觉上“排成环形”fixPosition()松手或调用next/prev时若位移越界则把轨道瞬移lockDuration true回合法位置再通过doubleRaf解锁过渡动画clampIndex/getSwipeIndex/swipeIndexToIndex把越界的“物理索引”如-1或length换算回逻辑索引例如循环模式下swipeIndex -1即当前为最后一页。非循环模式则简单得多clamp(index, 0, length - 1)直接封顶这也是loop: false时无法继续滑动的根本原因。自动播放与组件生命周期自动播放由startAutoplay()/stopAutoplay()管理setTimeout到期调用next()后再次startAutoplay()形成递归定时链。关键挂接点包括handleTouchstart立即停止播放handleTouchend恢复播放——用户手动交互优先onSmartUnmounted卸载时停止避免内存泄漏与Popup联动usePopup弹层重新显示时resize并恢复关闭时停止自动播放onWindowResize与onActivated时重绘。父子通信provide/injectSwipe与SwipeItem通过varlet/use的useChildren/useParent建立父子关系通信键定义在 provide.tsSWIPE_BIND_SWIPE_ITEM_KEY父组件收集全部SwipeItem得到length与各子项引用用于计算轨道尺寸、分发平移与定位SWIPE_RESIZE_DISPATCHER_BIND_SWIPE_RESIZE_LISTENER_KEY允许其他组件如与轮播联动的模块注册onResize回调在resize()时统一触发。SwipeItem.vue 从父级读取size、currentIndex、vertical据此设置自身宽高与translate并通过assert保证“var-swipe-item必须位于var-swipe内”否则直接报错提示见 swipe-item/provide.ts。键盘方向键支持Swipe.vue 额外监听了window的keydown当某个swipe-item处于聚焦状态isFocusing由tabindex-1与 focus/blur 事件维护时按ArrowLeft调用prev()、按ArrowRight调用next()实现桌面端的键盘无障碍操作。测试用例swipe keyboard Arrow通过triggerKeyboard模拟了聚焦、左右方向键切换的完整流程。总结Swipe组件把移动端轮播最常见的需求——循环切换、自动播放、垂直方向、导航按钮、事件监听、自定义指示器——收敛为极简的声明式属性同时通过轨道平移、触摸方向判定、无缝回绕与父子注入等机制保证了顺滑的交互体验。对于常规业务掌握文档中的属性和插槽即可完成 90% 的场景若需要更精细的控制如手动resize、以SwipeToOptions.event: false静默跳页、自定义导航按钮或按StyleProvider定制主题则可结合 Swipe.vue、props.ts 与 swipe.less 深入探索相关行为均有 index.spec.js 中的测试用例背书可作为二次开发的参考基线。赞分享UI组件前端【免费下载链接】varletA Vue3 component library based on Material Design 2 and 3, supporting mobile and desktop.项目地址https://gitcode.com/gh_mirrors/va/varlet点击查看免费下载相关推荐Vant 4 Swipe 轮播组件完全指南从基础用法到源码级实现解析Vant 4 Swipe 轮播组件完全指南从基础用法到源码级实现解析 Swipe轮播是 Vant 4 中最常用的移动端组件之一用于循环播放一组图片或内容前端UI组件Element Plus Carousel 轮播组件完全指南从基础用法到源码级原理Element Plus Carousel 轮播组件完全指南从基础用法到源码级原理 轮播图Carousel是在有限空间内循环展示一系列图片或文本的经典 U前端UI组件Varlet 徽标Badge组件完全指南从基础用法到源码原理Varlet 徽标Badge组件完全指南从基础用法到源码原理 本指南以 Varlet UI基于 Vue 3 与 Material Design 2/3UI组件前端创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考