首先tab的滑动
如图效果
<div id="apps"> <nav> <p v-for="(item,$index) in arrs" @click="toggle($index)" :class="{active:$index==active}" >{{item}}</p> </nav> </div>
在data中的参数,和点击事件,文章结尾有修改后的toggle事件,点击切换内容
data() { return { active: 0, arrs: ["菜单1", "菜单2", "菜单3", "菜单3",'菜单5','菜单6','菜单7'] }; }, methods: { toggle(index) { this.active = index; },
style样式
#apps{ width: 100%; overflow:hidden; } #apps nav{ padding: 0 10px; display: -webkit-box; display: -ms-flexbox; display: flex; -webkit-box-align: middle; -ms-flex-align: middle; align-items: middle; overflow: auto; } #apps p{ text-align: center; font-size: 16px; -ms-flex-negative: 0; flex-shrink: 0; padding: 10px; margin: 5px; } #apps p.active{ color: #ffff00; background-color: #000000; }
这是tab的滑动代码
接下来是,内容页的滑动切换div和tab的动画的实现代码
页面代码如下:
<div class="back" @touchstart.prevent="touchStart" @touchmove.prevent="touchMove" @touchend="touchEnd" ref="back" > <div class="back-l" ref="left"></div> <div class="back-m" ref="middle"></div> <div class="back-r" ref="right"></div> </div>
样式:
<style scoped lang="stylus" rel="stylesheet/stylus"> .back { position: fixed; width: 100%; height: 100px; white-space: nowrap; .back-l { position: relative; vertical-align: top; display: inline-block; width: 100%; height: 100%; background-color: red; } .back-m { position: relative; vertical-align: top; display: inline-block; width: 100%; height: 100%; background-color: blue; } .back-r { display: inline-block; vertical-align: top; position: relative; width: 100%; height: 100%; background-color: yellow; } } </style>
没有安装stylus的使用以下命令安装使用
npm install stylus stylus-loader --save-dev
以下是js代码
js中data参数:
data() { return { active: 0, currentPlay: "red", percent: 0, arrs: ["red", "blue", "yellow"] }; },
滑动动作开始:
touchStart(e) { const touch = e.touches[0]; this.touch.startX = touch.pageX; this.touch.startY = touch.pageY ; },
滑动动作:
touchMove(e) { const touch = e.touches[0]; //横向和纵向偏离位置 const deltaX = touch.pageX - this.touch.startX; const deltaY = touch.pageY - this.touch.startY; if (Math.abs(deltaY) > Math.abs(deltaX)) { return; } if(this.currentPlay=='red'){ var left=0; var offsetWidth = Math.min( 0, Math.max(-window.innerWidth, left + deltaX) ); } else if(this.currentPlay=='blue'){ var left=-window.innerWidth; if(deltaX>0){ //判断动作 是左滑还是右滑 var offsetWidth = Math.min( 0, Math.max(-window.innerWidth, left + deltaX) ); }else{ var offsetWidth = Math.min( -window.innerWidth, Math.max(-window.innerWidth*2, left + deltaX) ); } } else{ var left=-window.innerWidth*2; var offsetWidth = Math.min( -window.innerWidth, Math.max(-window.innerWidth*2, left + deltaX) ); } //记录滑动的距离占屏幕宽度的百分比,如果滑动太少则不切换 this.percent = deltaX / window.innerWidth; //动画中滑块的移动 this.$refs.back.style["transform"] = `translate3d(${offsetWidth}px,0,0)`; //设置动画时间 this.$refs.back.style["transitionDuration"] = 10; console.log(''); },
这个方法简单的介绍一下几个参数把,个人的理解修改offsetWidth ,参数的变化就可以在滑动时产生动画效果,
当最左边滑块时(red)
也就是red的时候offsetWidth= Math.min(0, Math.max(-window.innerWidth, left + deltaX));
当前Math.min中的第一个参数是当前滑块div左边的x坐标为0,Math.max中的第一个参数为当前滑块右边的x的坐标,
当滑块在中间时(blue)
判断当前动作时左滑还是右滑,当左滑时 左边模块为red所以
offsetWidth=Math.min(0, Math.max(-window.innerWidth, left + deltaX));
右滑是为yellow
var offsetWidth = Math.min(-window.innerWidth,Math.max(-window.innerWidth2, left + deltaX));
当前Math.min中的第一个参数是当前滑块div左边的x坐标为-window.innerWidth,Math.max中的第一个参数为当前滑块右边的x的坐标
当滑块在中间时(yellow)
也就是yellow的时候var offsetWidth = Math.min( -window.innerWidth,Math.max(-window.innerWidth2, left + deltaX));
当前Math.min中的第一个参数是左边滑块div左边的x坐标为0,Math.max中的第一个参数为左边滑块右边的x的坐标
滑动结束的js:
touchEnd() { let offsetWidth; let percent; //当前为红色,滑动占比小于-0.1则切换,否则回到原位置 if (this.currentPlay === "red") { if (this.percent < -0.1) { this.currentPlay = "blue"; this.active=1; offsetWidth = -window.innerWidth; } else { offsetWidth = 0; } }else if(this.currentPlay === "blue"){ if (this.percent > 0.1) { this.active=0; this.currentPlay = "red"; offsetWidth = 0; } else if (this.percent < -0.1) { this.currentPlay = "yellow"; this.active=2; offsetWidth = -window.innerWidth*2; } else { offsetWidth = -window.innerWidth; } } else { //当前为黄色,滑动占比大于0.9则切换,否则回到原位置 if (this.percent > 0.1) { this.currentPlay = "blue"; this.active=1; offsetWidth = -window.innerWidth; } else { offsetWidth = -window.innerWidth*2; } } //这里的transform是针对最开始的位置而言,而不是移动过程中的位置 this.$refs.back.style["transform"] = `translate3d(${offsetWidth}px,0,0)`; this.$refs.back.style["transitionDuration"] = 10; }
补上一个点击tab是切换内容
修改js中的toggle方法,修改成这样,就能同时满足点击切换或者滑动切换
toggle(index) { this.active = index; if(index==0){ var offsetWidth = 0; this.currentPlay = "red"; } else if(index==1){ var offsetWidth = -window.innerWidth; this.currentPlay = "blue"; } else if(index==2){ this.currentPlay = "yellow"; var offsetWidth = -window.innerWidth*2; } //这里的transform是针对最开始的位置而言,而不是移动过程中的位置 this.$refs.back.style["transform"] = `translate3d(${offsetWidth}px,0,0)`; },
以上就是实现的全部代码,参考与 https://blog.csdn.net/tjzc1352640/article/details/79381155 和 https://blog.csdn.net/jinyuyang78/article/details/78958527 。 在这两个基础上做了自己的理解和改动,如果需要多个tab菜单和页面添加修改 touchMove 和 touchEnd 中的两个判断中的内容即可。