中期完了可以安心写了,小白一个,写的不对多多指教
- useParent 和 useChildren 使用 provide/inject 实现跨组件间通信
- getCurrentlnstance 获取组件实例
- useExpose实现暴露组件方法
- useTouch 实现 touch 事件封装
- useEventListener 实现事件监听
- onMountedOrActivated 封装生命周期
需求分析
- 如何在 Swipe 里获取到 Swipeltem 实例?典型的跨组件通信问题
01.定义了一个名为 OpSwipe
的 Vue 3 组件,使用 TypeScript 和 JSX 书写。该组件实现了一个滑动轮播(swipe carousel)功能,允许用户通过触摸滑动来浏览多个子元素。以下是这段代码的核心逻辑和组件的主要功能:
- 滑动逻辑:组件能够响应用户的触摸滑动,根据滑动的速度和距离决定是回弹还是切换到下一个项目。
- 自动播放:当设置了
autoplay
属性时,组件会自动滚动到下一个项目。 - 循环滚动:支持循环播放,即从最后一个项目滑动到第一个项目。
- 指示器:可选地显示指示器,表明当前活跃的项目。
02为什么要写成tsx
1. 类型安全和静态类型检查
- TypeScript 提供了静态类型检查,这意味着你可以在编译时捕获许多潜在的错误,而不是在运行时。这使得代码更加健壮和易于维护。
- 在复杂的应用中,尤其是在大型项目或团队合作环境下,类型检查可以显著减少错误和提高代码质量。
2. 使用 JSX/TSX 的优势
- JSX/TSX 允许你以更接近 JavaScript 的方式编写模板代码,这对于某些开发者来说可能更自然,特别是对于那些习惯于 React 开发的人。
- 它提供了更强的表达能力,可以在模板中更方便地使用 JavaScript 表达式。
- TSX 与 TypeScript 的结合使用可以提供更好的类型推断和自动补全,特别是在处理组件的 props、事件等方面。
3. 现代前端开发实践
- 使用 TypeScript 和 TSX 是现代前端开发的趋势之一,它符合渐进式的开发理念。
- 许多新的前端项目和框架都在积极采用 TypeScript,因为它提供了更严格的编码标准和更好的工程化体验。
4. 提高项目的可维护性
- TypeScript 的强类型特性使得代码更易于理解和维护,特别是在项目规模较大或者跨团队协作时。
- 类型定义和接口可以作为代码的文档,帮助开发者理解组件的用途和使用方式。
总结
将 Vue 组件编写为 .tsx
文件是一种结合了 Vue 的响应式系统和 TypeScript 类型安全性的编程实践。它旨在提供更强大的开发体验和更高的代码质量,尤其适用于复杂或大型的前端应用开发。
03为什么使用tsx而不是组件
在 Vue 中,选择使用 .tsx
文件格式还是传统的单文件组件(.vue
文件)格式主要取决于几个关键因素:项目需求、团队习惯、类型安全需求,以及对 JSX/TSX 的偏好。下面是一些决定使用哪种格式的考虑点:
使用 .vue
文件的情况
- 标准Vue特性:如果你主要使用标准的Vue特性,如模板语法、样式封装、Vue指令等,
.vue
文件是最直接的选择。 - 团队习惯和经验:如果你的团队更熟悉 Vue 的标准语法和生态系统,使用
.vue
文件可以减少学习曲线。 - 更好的工具支持:对于
.vue
文件,Vue 社区提供了广泛的工具支持,如 Vue DevTools、Vetur 等。 - 单文件组件的优势:
.vue
文件将模板、脚本和样式封装在一个文件中,这对于组件的组织和维护非常方便。
使用 .tsx
文件的情况
- TypeScript的完全集成:如果你需要在组件中利用 TypeScript 的全部功能,特别是复杂类型推断和强类型检查,
.tsx
文件是更好的选择。 - JSX/TSX 的偏好:如果你更喜欢使用 JSX/TSX 进行模板编写(可能是因为你有 React 开发背景),那么
.tsx
是合适的。 - 复杂逻辑或大型项目:在具有复杂逻辑或大型项目中,使用 TypeScript 可以提供更好的代码组织和维护性。
- 更灵活的代码结构:
.tsx
提供了在组件内直接使用 JavaScript/TypeScript 的能力,这在某些情况下可能更灵活。
总结
- 如果你的项目或团队更适合 Vue 的标准特性和工具,且不需要 TypeScript 的全部能力,那么
.vue
文件是更合适的选择。 - 如果你需要强类型检查、更喜欢 JSX/TSX,或者你的项目需要复杂的类型逻辑,
.tsx
文件会是更好的选择。
在许多情况下,这两种格式可以在同一个项目中共存,你可以根据具体组件或特定需求选择最适合的格式。
04组件实现滑动功能
OpSwipe
组件的滑动功能主要是通过监听和处理触摸事件来实现的
-
使用自定义钩子
useTouch
:- 这个钩子可能是用来处理触摸事件的,如记录触摸开始、移动和结束时的位置。
- 它可能提供了如
touch.start()
,touch.move()
, 和touch.end()
这样的方法来相应地处理不同阶段的触摸事件。
-
触摸事件监听:
- 在组件中,通过
onTouchStart
,onTouchMove
, 和onTouchEnd
方法来监听触摸事件。 - 这些方法分别在用户开始触摸、移动手指和手指离开屏幕时被触发。
- 在组件中,通过
-
计算移动距离:
- 在
onTouchMove
方法中,组件会计算手指移动的距离。这是通过比较触摸开始和移动时的位置来实现的。 - 这个距离用来决定轮播项应该移动多远。
- 在
-
更新轨道的位置:
- 组件中有一个轨道(track),轮播的内容就在这个轨道上。
- 根据手指移动的距离,通过修改轨道的
transform
属性(translateX
或translateY
),来实现轮播内容的滑动效果。
-
处理滑动结束:
- 当用户手指离开屏幕时,
onTouchEnd
方法会被触发。 - 这时,组件会根据最终的滑动距离和速度决定是恢复到当前轮播项还是滑动到下一个轮播项。
- 当用户手指离开屏幕时,
-
动画和平滑过渡:
- 为了使滑动看起来平滑,组件可能使用了 CSS 过渡效果(例如,通过
transition
属性)。 - 这确保了即使在手指离开屏幕后,轨道的移动也是平滑的。
- 为了使滑动看起来平滑,组件可能使用了 CSS 过渡效果(例如,通过
-
循环滑动逻辑:
- 如果启用了循环滑动(
loop
prop),组件在滑动到最后一项或第一项时会相应地更新轨道的位置,以实现无缝循环的效果。
- 如果启用了循环滑动(
通过这些步骤,OpSwipe
组件实现了一个流畅且可交互的滑动轮播功能。这种实现方式适用于触摸设备,并且通过动态调整轨道位置,提供了良好的用户体验。
05useTouch钩子常用属性和事件
常用属性
-
startX
和startY
:- 存储触摸开始时的 X 和 Y 坐标。
- 使用
ref
创建,以保持响应式。
-
deltaX
和deltaY
:- 分别存储从触摸开始到当前位置的水平(X轴)和垂直(Y轴)移动距离。
-
offsetX
和offsetY
:- 存储触摸点移动的总水平和垂直距离的绝对值。
- 用于确定触摸的总位移。
-
direction
:- 存储触摸移动的主要方向('horizontal' 或 'vertical')。
-
isVertical
和isHorizontal
函数:- 基于
direction
值提供方便的方法来判断触摸方向。
- 基于
常用事件
- 触摸事件:
touchstart
:当用户开始触摸屏幕时触发,通过start
函数处理。touchmove
:当用户在屏幕上移动手指时触发,通过move
函数处理。
功能实现
- 方向判断:使用
getDirection
函数基于offsetX
和offsetY
来判断触摸滑动的主要方向。 - 事件处理逻辑:
- 在
start
方法中,记录触摸开始时的位置。 - 在
move
方法中,计算当前触摸点与开始点的相对移动距离,并判断滑动方向。
- 在
06useTouch钩子基本逻辑
1. 初始化状态
- 使用 Vue 的
ref
创建一组响应式变量来存储触摸事件相关的数据,如触摸的起始点 (startX
,startY
),当前触摸点相对于起始点的位移 (deltaX
,deltaY
),以及这些位移的绝对值 (offsetX
,offsetY
)。
2. 触摸开始
- 定义
start
方法来处理触摸开始(touchstart
)事件。 - 在触摸开始时记录触摸点的位置,并重置其他相关数据,为后续的移动计算做准备。
3. 触摸移动
- 定义
move
方法来处理触摸移动(touchmove
)事件。 - 计算触摸点相对于起始点的位移,并更新响应式变量。
- 判断触摸的主要方向(水平或垂直),这通常基于水平位移和垂直位移的比较。
4. 方向判断逻辑
- 使用
getDirection
函数根据位移的绝对值来判断触摸的主要方向。 - 这个方向信息可以用于决定如何响应触摸动作,例如在轮播组件中是滑动图片还是允许页面滚动。
5. 方向锁定
- 在一定的偏移距离内锁定方向判断,以避免在小范围内的触摸波动导致方向判断频繁变化。
6. 提供辅助函数
isVertical
和isHorizontal
函数基于当前的direction
提供了快速判断触摸方向的方法。
7. 重置功能
reset
方法用于重置所有相关数据,为下一次触摸做准备。
07useTouch钩子
方向锁定基本逻辑
1. 设置阈值
首先,定义一个阈值(如 const LOCK_DIRECTION_DISTANCE = 10
),表示用户触摸移动达到多少像素后才开始判断方向。
2. 初始化方向
在触摸开始时(touchstart
事件),初始化方向为未定义(direction.value = ''
)。
3. 计算移动距离
在触摸移动过程中(touchmove
事件),计算触摸点的水平和垂直移动距离(deltaX
, deltaY
)及其绝对值(offsetX
, offsetY
)。
4. 判断方向
在每次 touchmove
事件中,使用以下逻辑来判断和锁定方向:
- 首先检查是否已经锁定了方向(即
direction.value
是否非空)。 - 如果方向未锁定,检查当前的移动距离(
offsetX
和offsetY
)是否超过了阈值(LOCK_DIRECTION_DISTANCE
)。 - 如果超过阈值,使用
getDirection
函数根据offsetX
和offsetY
的值来确定是水平移动还是垂直移动,并设置direction.value
。
5. 锁定后的处理
一旦方向被锁定,后续的 touchmove
事件将不会改变这个方向,除非触摸结束并重新开始。这样可以确保在一次完整的触摸操作中,滑动方向保持一致。
6. 辅助函数
提供 isVertical
和 isHorizontal
辅助函数,基于当前的 direction.value
提供快速判断触摸方向的方式。