首页/心系八方/正文
Taro UI框架开发小程序:左滑喜欢右滑不喜欢效果示例代码解析

 2025年06月22日  阅读 1

摘要:TaroUI框架实现小程序左滑喜欢右滑不喜欢效果背景介绍Taro是一款基于React语法开发的小程序工具,它具备跨平台的功能,能够将编写的代码转换为适用于微信、百度、支付宝等多个小程序平台的版本,并且还能兼容H5和RN等多种应用环境。在项目开发的实际过程...

Taro UI框架实现小程序左滑喜欢右滑不喜欢效果

背景介绍

Taro是一款基于React语法开发的小程序工具,它具备跨平台的功能,能够将编写的代码转换为适用于微信、百度、支付宝等多个小程序平台的版本,并且还能兼容H5和RN等多种应用环境。在项目开发的实际过程中,我们常常遇到需要引入类似于Tinder应用中的卡片滑动功能的需求。此功能一般采用向左滑动来表示用户的不感兴趣态度,而向右滑动则用来表达用户的兴趣所在。

问题发现

接手任务后,我注意到iOS和Android版本已成功实现了卡片滑动功能。然而,H5和小程序版本由于缺乏现成的插件和资料支持,该功能尚未实现。经过深入调查,我发现我们能够利用小程序中的可拖动组件movable-view来达成这一效果。

基本原理

实现这一效果的核心在于监听卡片的拖动事件:

1. 使用movable-view组件作为卡片容器

2. 监听onTouchStart获取初始触摸位置

3. 监听onChange获取拖动过程中的位置变化

4. 监听onTouchEnd判断最终滑动方向


 
 ......
 

实现步骤

1. 基础拖动实现

首先创建一个可拖动的卡片组件:


<MovableArea style={{width: '100%', height: '100%'}}>
  <MovableView 
    direction="all"
    onTouchStart={this.handleTouchStart}
    onChange={this.handleChange}
    onTouchEnd={this.handleTouchEnd}
  >
    {/ 卡片内容 /}
  </MovableView>
</MovableArea>


 
 ......
 

// 触发方法,打印参数
onChange(e) {
 console.log('参数',e);
}

2. 事件处理逻辑

处理触摸开始事件,记录初始位置:

 
<--中间加入图片之类的滑动内容-->


handleTouchStart = (e) => {
此处所设定的起始横坐标,正是基于事件触发的瞬间,根据客户端上第一个触摸点所对应的横坐标值来确定的。
}

state = { 
 x: '16', 
 y: '16', 
 like: false, 
 unlike: false, 
 shopList: [ 
 { 
 img: 'https://edgefix-image.edgecom.top/ABD846F6672997A7F76CD38E8A57F954.jpg', 
 }, 
 { 
 img: 'https://edgefix-image.edgecom.top/F6E5801C304CC76DA63C02C9FB38B8F4.jpg', 
 }, 
 { 
 img: 'https://edgefix-image.edgecom.top/D518952AD1DD61B2D32556E20CC527C4.jpg', 
 }, 
 { 
 img: 'https://edgefix-image.edgecom.top/1D187E28B349679908A44BBE81F3D3CA.jpg', 
 }, 
 { 
 img: 'https://edgefix-image.edgecom.top/1129A411AC9CF5F81187CBED181B6F57.jpg', 
 } 
 ] 
 }

3. 滑动方向判断

在触摸结束时判断滑动方向:

handleTouchEnd = (e) => {

endX的数值与事件e的changedTouches数组中的第一个元素的clientX属性值相对应。

定义变量deltaX,其值由endX与this.startX的差值确定。

if(deltaX > 50) { // 右滑

this.likeAction()

// 触摸触发 

Taro UI实现卡片滑动效果教程_Taro UI框架左滑右滑效果小程序代码_taro小程序开发案例

onTouchStart(e) { console.log('222',e.touches[0].pageX); this.setState({ x: e.touches[0].pageX, y: e.touches[0].pageY, }); } // 触摸移动 onTouchMove(e) { console.log('333',e.touches[0].pageX); let dx = e.touches[0].pageX - this.state.x; if (dx > 50) { this.setState({ like: true, unlike: false, }); } else if (dx < -50) { this.setState({ like: false, unlike: true, }); } else { this.setState({ like: false, unlike: false, }); } } // 取消 onCancel(e) { console.log('444',e.changedTouches[0].pageX); this.setState({ x: '16', y: '16', like: false, unlike: false, }); }

} else if(deltaX < -50) { // 左滑

} else { // 回弹效果

// 恢复原位

}

style={{transform:'rotate('+this.state.tiltAngle[index]+'deg)'}}

}


<b>4. 多卡片处理</b>
当有多张卡片时,需要为每张卡片维护独立的状态:
state = {
  cards: [
该记录编号为1,其横坐标和纵坐标均为0,且未标记为喜爱。
    // ...
  ]
}

// 拖动后相差距离进行换算角度
let dxangle = (e.touches[0].pageX - this.state.startX) * 45 / 500;

优化与注意事项

1. 性能优化

使用key属性确保卡片渲染效率

避免不必要的状态更新

2. 动画效果


可以添加过渡动画使滑动更加自然:


.movable-view {
过渡效果:实现0.3秒的平滑变化;
}

3. 常见问题

确保MovableArea有足够的空间

state = {
 // 开始位置
 startX: '',
 // 开始位置-最终位置距离
 placeX: '',
 // 倾斜角度
 tiltAngle: ['0','0','0','0','0'],
 // 坐标
 x: ['16','16','16','16','16'],
 y: ['16','16','16','16','16'],
 // 是否喜欢状态
 like: [false,false,false,false,false],
 unlike: [false,false,false,false,false],
 // 推荐商品数组
 shopList: [
 {
 id: 1,
 img: 'https://edgefix-image.edgecom.top/ABD846F6672997A7F76CD38E8A57F954.jpg',
 },
 {
 id: 2,
 img: 'https://edgefix-image.edgecom.top/F6E5801C304CC76DA63C02C9FB38B8F4.jpg',
 },
 {
 id: 3,
 img: 'https://edgefix-image.edgecom.top/D518952AD1DD61B2D32556E20CC527C4.jpg',
 },
 {
 id: 4,
 img: 'https://edgefix-image.edgecom.top/1D187E28B349679908A44BBE81F3D3CA.jpg',
 },
 {
 id: 5,
 img: 'https://edgefix-image.edgecom.top/1129A411AC9CF5F81187CBED181B6F57.jpg',
 }
 ]
 }

注意z-index层级关系

处理边界情况,如最后一张卡片

完整示例代码


在引入Taro库的Component组件时,我们需借助from关键字,以明确标识该组件的来源为@tarojs/taro模块。
我们采纳了源自 '@tarojs/components' 的 View 元素、可移动区域组件以及可移动视图组件。
class SwipeCards 是由 Component 类所继承的一个子类。
  state = {
    cards: [
      {id: 1, x: 0, y: 0},
    ]
  }
处理触摸开始事件 = (事件对象, 索引值) => {
    const { cards } = this.state
在index所指定的卡片实体中,对startX属性进行赋值操作,该值应与事件e的changedTouches数组中的第一个元素所对应的clientX坐标相一致。
    this.setState({ cards })
endX数值与事件对象的changedTouches数组中第一个元素的clientX属性所承载的信息相吻合。
定义deltaX变量,其数值应当等于endX减去cards数组中index位置对应的startX属性值。
    
    if(Math.abs(deltaX) > 50) {
      if(deltaX > 0) {
        // 调用喜欢接口
      } else {
      }
      // 移除当前卡片
      cards.splice(index, 1)
      // 恢复原位
      cards[index].x = 0
    }
  }
  render() {
    return (
      <View className='container'>
在state.cards数组里,每一项都必须经过.map()函数的遍历流程,接着,每个card元素以及它对应的索引index会被逐一提取出来,并接受相应的处理措施。
          <MovableArea key={card.id} className='movable-area'>
              className='movable-view'
              direction='all'
              x={card.x}
在触控动作被激活的瞬间,系统会激活一个名为handleTouchStart的程序来处理这一情况,并且会一并传入事件本身以及相应的索引值index作为必须的参数。
                {/ 卡片具体内容 /}
        ))}
      </View>
    )
  }
}

// 触摸触发
 onTouchStart(index,e) {
 console.log('1111',index,e.touches[0].pageX,e.touches[0].pageY);
 // 重定义数组
 var againX = [];
 var againY = [];
 // 遍历,判断拖动的该数组的位置
 for (var i=0; i

总结

依托于Taro框架的movable-view组件,我们能够轻松完成小程序中卡片间的滑动操作。这一功能的实现,需要精确处理触摸操作和位置变化,同时还要关注多张卡片的状态管理以及性能的优化。此外,这种方法同样适用于其他需要类似交互功能的场景。

版权声明:本文为 “博览广文网” 原创文章,转载请附上原文出处链接及本声明;

原文链接:http://wen.bjhwtx.com/post/34257.html

标签:

博览广文网

博览广文网为所有文学爱好者、新闻爱好者、关注生活多方面内容的观众朋友提供多方位的内容呈现、提升阅读空间、填充碎片时间,开阔读者的视野、增长见识、了解民生、一个让您不出户尽知天下事的网站平台!
热门标签
关于我们
广文舒阅网—让天下读者有家可归!这里汇聚了各类优质文化信息,无论是全球热点、历史故事,还是实用百科、趣味探索,您都能轻松获取。我们希望用阅读点亮您的世界,让每一次浏览都充满收获和乐趣。
导航栏A标题
广文舒阅网
扫码关注
联系方式
全国服务热线:0755-88186625
Q Q:8705332
Email:admin@lanyu.com
地址:深圳市福田区海雅缤纷国际大厦5层501
Copyright 深圳市蓝宇科技有限公司 版权所有 备案号:京ICP备20013102号-1