中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Taro UI框架開發小程序如何實現左滑喜歡右滑不喜歡效果

發布時間:2020-07-23 15:45:08 來源:億速云 閱讀:343 作者:小豬 欄目:web開發

這篇文章主要為大家展示了Taro UI框架開發小程序如何實現左滑喜歡右滑不喜歡效果,內容簡而易懂,希望大家可以學習一下,學習完之后肯定會有收獲的,下面讓小編帶大家一起來看看吧。

Taro 就是可以用 React 語法寫小程序的框架,擁有多端轉換能力,一套代碼可編譯為微信小程序、百度小程序、支付寶小程序、H5、RN等

摘要:

年后入職了一家新公司,與前同事交接完之后,發現公司有一個四端的項目(iOS,Android,H5,小程序),iOS和安卓都實現了左滑右滑的效果,而h6和小程序端沒實現,詢問得知前同事因網上沒找到對應的插件,相關博客也特別少,所以沒做就擱置下來了。

趁這段時間相對來說比較富裕,于是乎在網上也搜索了一下,發現確實很少,但是有人提到可以用小程序可拖動組件movable-view來實現,自己嘗試來一下發現可行,于是來寫這篇博客記錄一下,希望能幫助到后面需要用到這個功能的人!

先上效果圖:

Taro UI框架開發小程序如何實現左滑喜歡右滑不喜歡效果

主要技術:Taro+Taro UI+React(如果你是小程序原生或者uniapp+vue寫法都差不多,可以通用)

可拖動組件文檔地址:

Taro:https://taro-docs.jd.com/taro/docs/components/viewContainer/movable-view.html

微信小程序:https://developers.weixin.qq.com/miniprogram/dev/component/movable-view.html

思路:

一,我們首先把movable-area和movable-view標簽寫出來;

<movable-area>
 <movable-view>
 ......
 </movable-view>
</movable-area>

二,我們可以看到文檔里面有一個onChange方法,即拖動過程中觸發的事件;

<movable-area>
 <movable-view onChange ={this. onChange.bind(this)}>
 ......
 </movable-view>
</movable-area>

// 觸發方法,打印參數
onChange(e) {
 console.log('參數',e);
}

我們可以看到打印出了,拖動的位置和產生移動的原因等;

三,我們接著加入開始onTouchstart,移動onTouchmove,結束onTouchcancel,onTouchend三個事件方法;

<MovableView 
 key={item.id} 
 onTouchcancel={this.onCancel} 
 onTouchend={this.onCancel} 
 onTouchstart={this.onTouchStart} 
 onTouchmove={this.onTouchMove} 
 x={this.state.x} // 橫坐標位置
 y={this.state.y} // 縱坐標位置
 direction='all' // 移動方向都可以
 outOfBounds // 可超過可移動區域
 className='shop-imgbox' 
> 
<--中間加入圖片之類的滑動內容-->
</MovableView>

初始數據如下:

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', 
 } 
 ] 
 }

三個方法我們可以取到移動后改變的位置,來改變喜歡與不喜歡的狀態css,以及實現卡片滑動的效果:

1.觸摸觸發的時候,我們獲取到剛剛開始觸摸卡片的x,y的位置坐標;

2.在觸摸滑動時,我們通過滑動后的位置-滑動前的位置,來判斷距離多少來改變喜歡和不喜歡的值;

3.當手離開時,觸發取消事件,我們需要把狀態數據改為原始值,即回到最初的狀態;

// 觸摸觸發 
 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, 
 }); 
 }

當我們寫到這里,我們去拖動我們的卡片時,你會發現確實可以拖動,并且取消的時候會回到原點,但是同樣你也會發現一個問題,就是你拖動的時候,五張卡片都被觸發來移動的效果,出現了觸點混亂的問題,查找問題發現卡片共用了x,y,因此我們可以給每張卡片設置獨立的參數;

四,給每張卡片獨立的參數并且設置卡片傾斜度效果;

1.設置傾斜度效果

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

然后我們通過卡片移動位置計算出一個你決定合適的傾斜角度;

// 拖動后相差距離進行換算角度
let dxangle = (e.touches[0].pageX - this.state.startX) * 45 / 500;

2.設置獨立的參數

方法攜帶索引,我們取到對應的卡片index,來改變對應卡片的數據;

<MovableView 
 key={item.id}
 onTouchcancel={this.onCancel.bind(this,index)}
 onTouchend={this.onCancel.bind(this,index)}
 onTouchstart={this.onTouchStart.bind(this,index)}
 onTouchmove={this.onTouchMove.bind(this,index)}
 x={this.state.x[index]} 
 y={this.state.y[index]} 
 direction='all' 
 outOfBounds 
 className='shop-imgbox'
>
</MovableView>

同時,我們需要改變初始參數的形式為數組,我們通過索引改變對應卡片的值;

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',
 }
 ]
 }

方法我們就舉一個例子,比如onTouchStart方法,我們遍歷卡片數組,通過判斷索引來得到是那張卡片,從而來改變對應值

// 觸摸觸發
 onTouchStart(index,e) {
 console.log('1111',index,e.touches[0].pageX,e.touches[0].pageY);
 // 重定義數組
 var againX = [];
 var againY = [];
 // 遍歷,判斷拖動的該數組的位置
 for (var i=0; i<this.state.shopList.length; i++){
 if (i == index) {
 againX[i] = e.touches[0].pageX;
 againY[i] = e.touches[0].pageY;
 } else {
 againX[i] = '16';
 againY[i] = '16';
 }
 }
 // 賦值
 this.setState({
 startX: e.touches[0].pageX,
 x: againX,
 y: againY,
 });
 }

這樣,我們運行代碼,發現拖動第一張卡片不會影響到后面卡片的位置了,

同時,我們現在拖動卡片刪除的是數組,在實際項目中,我們在觸發刪除數組的地方接入接口,調用喜歡,不喜歡改變數據參數,從而也能改變數組的長度;

五,完整代碼;

下面我將貼出完整的代碼供大家參考

html文件:

import Taro, { Component } from '@tarojs/taro';
import { View, Image, Button, Text, MovableArea, MovableView } from '@tarojs/components';
import { observer, inject } from '@tarojs/mobx';
import { AtButton, AtFloatLayout } from 'taro-ui';
import userStore from '../../store/user.store';
import './stroll.scss';
@inject('userStore')
@observer
class Stroll extends Component {
 config = {
 navigationBarTitleText: '逛',
 }
 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',
 }
 ]
 }
 componentWillMount () { }
 componentWillReact () { }
 componentDidMount () {
 }
 // 觸摸觸發
 onTouchStart(index,e) {
 console.log('1111',index,e.touches[0].pageX,e.touches[0].pageY);
 // 重定義數組
 var againX = [];
 var againY = [];
 // 遍歷,判斷拖動的該數組的位置
 for (var i=0; i<this.state.shopList.length; i++){
 if (i == index) {
 againX[i] = e.touches[0].pageX;
 againY[i] = e.touches[0].pageY;
 } else {
 againX[i] = '16';
 againY[i] = '16';
 }
 }
 // 賦值
 this.setState({
 startX: e.touches[0].pageX,
 x: againX,
 y: againY,
 });
 }
 // 觸摸離開
 onTouchMove(index,e) {
 console.log('2222',index,e.touches[0].pageX,e.touches[0].pageY);
 // 重定義數組
 var tiltAngleT = [];
 var againX = [];
 var againY = [];
 // 拖動后相差距離
 let dxplace = e.touches[0].pageX - this.state.startX;
 // 拖動后相差距離進行換算角度
 let dxangle = (e.touches[0].pageX - this.state.startX) * 45 / 500;
 console.log(dxangle);
 // 遍歷,判斷拖動的該數組的位置
 for (var i=0; i<this.state.shopList.length; i++){
 if (i == index && dxplace > 50) {
 tiltAngleT[i] = dxangle,
 againX[i] = true;
 againY[i] = false;
 } else if (i == index && dxplace <= -50) {
 tiltAngleT[i] = dxangle,
 againX[i] = false;
 againY[i] = true;
 } else if (i == index && dxplace < 50 && dxplace > -50) {
 tiltAngleT[i] = dxangle,
 againX[i] = false;
 againY[i] = false;
 } else {
 tiltAngleT[i] = '0',
 againX[i] = false;
 againY[i] = false;
 }
 }
 // 賦值
 this.setState({
 placeX: dxplace,
 tiltAngle: tiltAngleT,
 like: againX,
 unlike: againY,
 });
 }
 // 取消
 onCancel(index,e) {
 console.log('3333',index,e.changedTouches[0].pageX,e.changedTouches[0].pageY);
 // 賦值
 this.setState({
 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],
 });
 // 如果偏移已經達到則清除第一張圖片
 if (this.state.placeX > 50 || this.state.placeX < -50) {
 this.setState({
 shopList: this.state.shopList.splice(1,4),
 });
 }
 }
 // 不喜歡按鈕點擊
 dislikebtn() {
 // 改變按鈕的狀態以及圖片位置及顯示
 this.setState({
 tiltAngle: ['-18','0','0','0','0'],
 x: ['-30','16','16','16','16'],
 y: ['267','16','16','16','16'],
 unlike: [true,false,false,false,false],
 }, () => {
 setTimeout( () => {
 this.setState({
  tiltAngle: ['0','0','0','0','0'],
  x: ['16','16','16','16','16'],
  y: ['16','16','16','16','16'],
  unlike: [false,false,false,false,false],
  shopList: this.state.shopList.splice(1,4),
 });
 },100);
 });
 }
 // 喜歡按鈕點擊
 likebtn() {
 // 改變按鈕的狀態以及圖片位置及顯示
 this.setState({
 tiltAngle: ['18','0','0','0','0'],
 x: ['284','16','16','16','16'],
 y: ['267','16','16','16','16'],
 like: [true,false,false,false,false],
 }, () => {
 setTimeout( () => {
 this.setState({
  tiltAngle: ['0','0','0','0','0'],
  x: ['16','16','16','16','16'],
  y: ['16','16','16','16','16'],
  like: [false,false,false,false,false],
  shopList: this.state.shopList.splice(1,4),
 });
 },100);
 });
 }
 componentWillUnmount () { }
 componentDidShow () {
 }
 componentDidHide () { }
 render() {
 return (
 <View className='stroll-tab'>
 <View className='stroll-text'>
  <Text className='text-tip1'>搭配師每天為你推薦5件單品</Text>
  <View className='text-tip2'>
  <Text className='t1'>右滑喜歡</Text>
  <Image src={require('./img/ic_like.png')} className='icon-image'></Image>
  <Text className='t1'>,左滑不喜歡</Text>
  <Image src={require('./img/ic_dislike.png')} className='icon-image'></Image>
  </View>
 </View>
 {
  this.state.shopList.length != 0&&
  <MovableArea className='stroll-shop'>
  {
  this.state.shopList&&this.state.shopList.map((item,index) => {
  return(
  <MovableView 
   key={item.id}
   onTouchcancel={this.onCancel.bind(this,index)}
   onTouchend={this.onCancel.bind(this,index)}
   onTouchstart={this.onTouchStart.bind(this,index)}
   onTouchmove={this.onTouchMove.bind(this,index)}
   x={this.state.x[index]} 
   y={this.state.y[index]} 
   direction='all' 
   outOfBounds 
   className='shop-imgbox'
  >
   <View className='images-box' style={{transform:'rotate('+this.state.tiltAngle[index]+'deg)'}}>
   <Image src={item.img} className='images'></Image>
   {
   this.state.like[index]==true&&
   <Image src={require('./img/text_like.png')} className='imagelike'></Image>
   }
   {
   this.state.unlike[index]==true&&
   <Image src={require('./img/text_dislike.png')} className='imageunlike'></Image>
   }
   </View>
  </MovableView>
  );})
  }
  </MovableArea>
 }
 {
  this.state.shopList.length === 0&&
  <View className='noshop-card'>
  <Image src={require('./img/noshop.png')} className='noshop-image'></Image>
  </View>
 }
 <View className='stroll-fotter'>
  {
  this.state.shopList.length != 0&&
  <View className='fot-twoimg'>
  {
  this.state.unlike[0]==false&&
  <Image src={require('./img/dislike_default.png')} className='dislike-image' onClick={this.dislikebtn.bind(this)}></Image>
  }
  {
  this.state.unlike[0]==true&&
  <Image src={require('./img/dislike_click.png')} className='dislike-image'></Image>
  }
  {
  this.state.like[0]==false&&
  <Image src={require('./img/like_default.png')} className='like-image' onClick={this.likebtn.bind(this)}></Image>
  }
  {
  this.state.like[0]==true&&
  <Image src={require('./img/like_click.png')} className='like-image'></Image>
  }
  </View>
  }
  <Text className='fot-text'>查看我喜歡的</Text>
 </View>
 </View>
 );
 }
}
export default Stroll;

css文件:

page {
 height: 100%;
 background: #F6F6F6;
}
.stroll-tab {
 width: 100%;
 min-height: 100vh;
 background: #F6F6F6;
 .stroll-text {
 width: 100%;
 margin-top: 40px;
 display: flex;
 flex-direction: column;
 align-items: center;
 .text-tip1 {
 font-size: 28px;
 color: #333333;
 }
 .text-tip2 {
 display: flex;
 flex-direction: row;
 align-items: center;
 .t1 {
 font-size: 28px;
 color: #333333;
 }
 .icon-image {
 width:20px;
 height:20px;
 }
 }
 }
 .stroll-shop {
 width: 100%;
 height: 700px;
 margin-top: 40px;
 .shop-imgbox {
 height: 600px;
 border-radius: 24px;
 .images-box {
 width: 100%;
 height: 520px;
 border-radius: 24px;
 box-shadow: 0px 2px 5px 0px rgba(0,0,0,0.1);
 background-color: #fff;
 position: relative;
 .images {
  width: 606px;
  height: 480px;
  position: absolute;
  left: 40px;
  top: 20px;
 }
 .imagelike {
  width: 96px;
  height: 48px;
  position: absolute;
  right: 40px;
  top: 20px;
 }
 .imageunlike {
  width: 148px;
  height: 48px;
  position: absolute;
  left: 40px;
  top: 20px;
 }
 }
 }
 .shop-imgbox:nth-child(1) {
 width: 686px;
 z-index: 50;
 }
 .shop-imgbox:nth-child(2) {
 width: 676px;
 z-index: 40;
 margin: 15px 0px 0px 5px;
 }
 .shop-imgbox:nth-child(3) {
 width: 666px;
 z-index: 30;
 margin: 30px 0px 0px 10px;
 }
 .shop-imgbox:nth-child(4) {
 width: 656px;
 z-index: 20;
 margin: 0px 0px 0px 15px;
 }
 .shop-imgbox:nth-child(5) {
 width: 646px;
 z-index: 10;
 margin: 0px 0px 0px 20px;
 }
 }
 .noshop-card {
 width: 100%;
 margin-top: 40px;
 padding: 0px 16px;
 .noshop-image {
 width: 100%;
 height: 806px;
 }
 }
 .stroll-fotter {
 width: 100%;
 display: flex;
 flex-direction: column;
 align-items: center;
 margin-top: 20px;
 .fot-twoimg {
 display: flex;
 flex-direction: row;
 align-items: center;
 .dislike-image {
 width: 120px;
 height: 120px;
 }
 .like-image {
 width: 120px;
 height: 120px;
 margin-left: 48px;
 }
 }
 .fot-text {
 color: #368BE5;
 font-size: 28px;
 margin-top: 40px;
 margin-bottom: 50px;
 }
 }
}

以上就是關于Taro UI框架開發小程序如何實現左滑喜歡右滑不喜歡效果的內容,如果你們有學習到知識或者技能,可以把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

于田县| 读书| 松滋市| 安顺市| 宿迁市| 临汾市| 察哈| 襄垣县| 通城县| 博客| 左云县| 包头市| 衡水市| 阿城市| 滦南县| 青神县| 金华市| 灵寿县| 自治县| 平罗县| 甘孜县| 广饶县| 宁城县| 贞丰县| 沈阳市| 自治县| 嘉祥县| 彰化市| 太仆寺旗| 渝北区| 曲周县| 岱山县| 广州市| 霍城县| 廊坊市| 文成县| 汝阳县| 宜城市| 茶陵县| 邹平县| 江山市|