-
Notifications
You must be signed in to change notification settings - Fork 5
feat(swiper): 实现 Swiper 轮播组件 #45
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
✅ Deploy Preview for skiyee-ui ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
概览引入了一个完整的Swiper轮播组件系统,包括SkSwiper、SkSwiperItem两个核心组件、TypeScript类型定义、样式配置以及八个功能演示示例页面。 文件变更
代码审查工作量🎯 3 (中等) | ⏱️ ~25 分钟 需要重点关注的区域:
诗
Pre-merge checks and finishing touches✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (3)
examples/uni/src/pages-basic/swiper/indicator.vue (1)
81-94: 考虑添加 v-model 绑定以保持一致性前三个轮播组件都使用了
v-model绑定来追踪当前索引,但这个无指示器的示例没有绑定。虽然无指示器场景下可能不需要显示当前索引,但为了示例的一致性和完整性,建议也添加v-model绑定。可以应用以下修改:
<SkSwiper + v-model="current3" indicator-type="none" height="200px" >或者如果希望使用独立的状态变量:
+const current4 = ref(0)<SkSwiper + v-model="current4" indicator-type="none" height="200px" >packages/skiyee-uni-ui/src/types/swiper.ts (2)
21-21: 未使用的类型定义
SwiperDirection类型已定义但在SwiperProps中未使用。组件通过vertical?: boolean属性(第 48 行)来控制方向,而不是使用方向类型。建议:
- 如果未来不打算使用此类型,考虑删除以避免代码冗余
- 或者重构
SwiperProps使用direction?: SwiperDirection替代vertical?: boolean,以获得更好的类型安全性和扩展性
36-61: 建议增强属性文档属性定义清晰,但以下几点可以改进:
height属性(第 58 行):当传入number类型时,未说明单位(是否为像素?)interval和duration(第 42-44 行):建议在注释中说明取值范围或约束(如"必须为正整数")modelValue属性(第 38 行):建议说明索引从 0 开始可以考虑这样改进文档:
/** 当前索引(v-model) */ - modelValue?: number; + modelValue?: number; // 从 0 开始 /** 是否自动播放 */ autoplay?: boolean; /** 自动切换间隔时间(毫秒) */ - interval?: number; + interval?: number; // 必须为正整数 /** 切换动画时长(毫秒) */ - duration?: number; + duration?: number; // 必须为正整数 ... /** 轮播高度 */ - height?: string | number; + height?: string | number; // number 类型时单位为 px
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (14)
examples/uni/src/pages-basic/swiper/autoplay.vue(1 hunks)examples/uni/src/pages-basic/swiper/base.vue(1 hunks)examples/uni/src/pages-basic/swiper/controlled.vue(1 hunks)examples/uni/src/pages-basic/swiper/custom.vue(1 hunks)examples/uni/src/pages-basic/swiper/indicator.vue(1 hunks)examples/uni/src/pages-basic/swiper/interval.vue(1 hunks)examples/uni/src/pages-basic/swiper/loop.vue(1 hunks)examples/uni/src/pages-basic/swiper/vertical.vue(1 hunks)packages/skiyee-uni-ui/src/components/sk-swiper-item.vue(1 hunks)packages/skiyee-uni-ui/src/components/sk-swiper.vue(1 hunks)packages/skiyee-uni-ui/src/styles/index.ts(1 hunks)packages/skiyee-uni-ui/src/styles/sk-swiper.ts(1 hunks)packages/skiyee-uni-ui/src/types/index.ts(1 hunks)packages/skiyee-uni-ui/src/types/swiper.ts(1 hunks)
🔇 Additional comments (17)
packages/skiyee-uni-ui/src/types/index.ts (1)
16-16: 代码变更符合预期类型导出语句与文件中其他导出保持一致,正确地将 swiper 相关类型暴露给外部使用。
examples/uni/src/pages-basic/swiper/indicator.vue (3)
1-32: 圆点指示器示例实现正确示例正确演示了带圆点指示器的轮播组件,使用
v-model绑定当前索引,代码清晰易懂。
34-53: 分数指示器示例实现正确示例正确演示了分数指示器的使用方式,与圆点指示器的模式保持一致。
55-74: 进度条指示器示例实现正确示例正确演示了进度条指示器的使用方式,与其他指示器类型保持一致的实现模式。
examples/uni/src/pages-basic/swiper/base.vue (1)
1-26: 基础示例实现正确这是一个清晰简洁的基础轮播示例,正确展示了 SkSwiper 组件的核心用法,包括
v-model双向绑定和当前页显示。代码结构合理,易于理解。packages/skiyee-uni-ui/src/styles/index.ts (1)
54-55: 样式导出符合规范新增的 Swiper 样式导出遵循了文件中现有的导出模式,并正确按字母顺序放置在 SkSpinner 和 SkSwitch 之间。
examples/uni/src/pages-basic/swiper/autoplay.vue (1)
1-45: 自动播放示例实现正确示例清晰地展示了自动播放功能,正确配置了
autoplay和interval属性,并提供了友好的说明文字。代码结构良好,易于理解。packages/skiyee-uni-ui/src/styles/sk-swiper.ts (2)
20-92: 样式组件定义完整且合理SkSwiperUcv 样式组件实现全面,包含了轮播组件所需的所有元素类和变体:
- 元素类定义清晰(root, swiper, indicator 等)
- 变体覆盖了常见使用场景(圆角、方向、指示器位置和类型等)
- 默认值设置合理
样式定义遵循了 ucv 系统的最佳实践,与其他组件样式保持一致。
94-94: 类型导出正确正确使用
InferProps从 ucv 组件定义中推导类型,为消费者提供类型安全。packages/skiyee-uni-ui/src/components/sk-swiper-item.vue (1)
1-51: SwiperItem 组件实现规范组件作为 uni-app 原生
swiper-item的简单封装,实现得当:
- 正确使用
inheritAttrs: false避免属性透传冲突itemId属性正确绑定到原生组件- 提供默认的 flex 布局样式便于内容居中
- 插槽使用正确,支持自定义内容
代码清晰简洁,符合组件封装的最佳实践。
examples/uni/src/pages-basic/swiper/vertical.vue (1)
1-48: 垂直方向示例实现正确示例很好地展示了垂直轮播的使用场景:
- 正确设置
vertical属性实现垂直滚动- 指示器位置设为右侧 (
indicator-position="right") 符合垂直布局的视觉习惯- 100px 的高度适合消息通知场景
- 2500ms 的自动播放间隔合理
代码清晰地演示了垂直轮播在实际场景中的应用。
examples/uni/src/pages-basic/swiper/interval.vue (1)
11-81: 示例实现清晰可读。 该示例完整展示了多组自动播放配置,状态绑定与样式处理均无不妥。examples/uni/src/pages-basic/swiper/loop.vue (1)
13-65: 循环与非循环示例表现良好。 属性配置与说明文字一致,便于用户理解差异。examples/uni/src/pages-basic/swiper/controlled.vue (1)
25-78: 受控模式示例逻辑稳健。 按钮与页码联动简洁明了,配合禁用态避免越界。examples/uni/src/pages-basic/swiper/custom.vue (1)
38-149: 多场景演示覆盖全面。 各配置段落彼此独立,能有效展示组件可定制性。packages/skiyee-uni-ui/src/types/swiper.ts (2)
63-75: 事件定义完善事件接口定义完整且符合 Vue 3 规范:
- ✅
update:modelValue正确支持 v-model 双向绑定- ✅ 提供了完整的生命周期事件(change、transition、animationfinish)
- ✅ 事件参数类型定义清晰
77-83: SwiperItem 定义合理
SwiperItemProps接口定义简洁且足够满足轮播子项的需求。可选的itemId属性为需要唯一标识的场景提供了支持。
| // 计算样式类 | ||
| const classes = computed(() => SkSwiperUcv({ | ||
| radius: props.radius, | ||
| vertical: props.vertical, | ||
| indicatorPosition: props.indicatorPosition, | ||
| indicatorType: props.indicatorType, | ||
| clax: props.clax, | ||
| })) | ||
|
|
||
| // 格式化高度 | ||
| const swiperHeight = computed(() => { | ||
| if (typeof props.height === 'number') { | ||
| return `${props.height}px` | ||
| } | ||
| return props.height | ||
| }) | ||
|
|
||
| // 指示器内容 | ||
| const indicatorContent = computed(() => { | ||
| if (props.indicatorType === 'fraction') { | ||
| return `${currentIndex.value + 1}/${totalCount.value}` | ||
| } | ||
| return '' | ||
| }) | ||
|
|
||
| // 进度条宽度 | ||
| const progressWidth = computed(() => { | ||
| if (totalCount.value === 0) { | ||
| return '0%' | ||
| } | ||
| return `${((currentIndex.value + 1) / totalCount.value) * 100}%` | ||
| }) | ||
|
|
||
| // 使用 ref 获取 swiper 实例以计算子项数量 | ||
| const swiperRef = ref<any>(null) | ||
|
|
||
| // 计算子项数量 | ||
| const updateTotalCount = () => { | ||
| // 这里需要通过 slot 内容来计算,暂时使用一个较大的默认值 | ||
| // 实际使用中会通过 slot 渲染后计算 | ||
| totalCount.value = 5 // 默认值,实际会在渲染后更新 | ||
| } | ||
|
|
||
| // 初始化时计算 | ||
| updateTotalCount() | ||
| </script> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
修复指示器总数硬编码导致的显示错误。 目前 totalCount 始终被写死为 5,导致圆点、分数和进度条指示器与真实幻灯片数量不符(例如只有 3 张图时仍显示 5 个指示点,分数模式会显示 1/5)。请改为根据默认插槽动态统计数量并响应更新。可参考以下修改:
-import { computed, ref, watch } from 'vue'
+import { computed, ref, watch, useSlots, watchEffect } from 'vue'
@@
-const totalCount = ref(0)
+const slots = useSlots()
+const totalCount = ref(0)
@@
-const updateTotalCount = () => {
- totalCount.value = 5 // 默认值,实际会在渲染后更新
-}
-
-// 初始化时计算
-updateTotalCount()
+watchEffect(() => {
+ totalCount.value = slots.default?.().length ?? 0
+})这样指示器即可与真实子项保持一致。
Committable suggestion skipped: line range outside the PR's diff.
#44
Summary by CodeRabbit
发布说明