vue移动端UI框架实现QQ侧边菜单组件

2020-06-16 06:14:03易采站长站整理


<template>
<div class="r-slide-menu">
<div class="r-slide-menu-wrap" :style="wrapStyle">
<slot name="menu"></slot>
</div>
<div class="r-slide-menu-content" :style="contentStyle"
@touchstart="touchstart"
@touchmove="touchmove"
@touchend="touchend">
<slot></slot>
</div>
</div>
</template>
<script>
export default {
props: {
width: {
type: String,
default: '250'
},
ratio: {
type: Number,
default: 2
}
},
data () {
return {
isMoving: false,
transitionClass: '',
startPoint: {
X: 0,
y: 0
},
oldPoint: {
x: 0,
y: 0
},
move: {
x: 0,
y: 0
}
}
},
computed: {
wrapStyle () {
let style = {
width: `${this.width}px`,
left: `-${this.width / this.ratio}px`,
transform: `translate3d(${this.move.x / this.ratio}px, 0px, 0px)`
}
return style
},
contentStyle () {
let style = {
transform: `translate3d(${this.move.x}px, 0px, 0px)`
}
return style
}
},
methods: {
touchstart (e) {},
touchmove (e) {},
touchend (e) {}
}
}

接下来,我们来实现我们最核心的touch事件处理函数,事件的逻辑如下:

手指按下瞬间,记录下当前手指所触摸的点,以及当前主容器的位置
手指移动的时候,获取到移动的点的位置
计算当前手指所在点移动的X、Y轴距离,如果X移动的距离大于Y移动的距离则判定为横向运动,否则为竖向运动
如果横向运动则判断当前移动的距离是在合理的移动区间(0到菜单宽度)移动,如果是则改变两个容器的位置(移动过程中阻止页面中其他的事件触发)
手指离开屏幕:如果累计移动距离超过临界值则运用动画打开菜单,否则关闭菜单


touchstart (e) {
this.oldPoint.x = e.touches[0].pageX
this.oldPoint.y = e.touches[0].pageY
this.startPoint.x = this.move.x
this.startPoint.y = this.move.y
this.setTransition()
},
touchmove (e) {
let newPoint = {
x: e.touches[0].pageX,
y: e.touches[0].pageY
}
let moveX = newPoint.x - this.oldPoint.x
let moveY = newPoint.y - this.oldPoint.y
if (Math.abs(moveX) < Math.abs(moveY)) return false
e.preventDefault()
this.isMoving = true
moveX = this.startPoint.x * 1 + moveX * 1
moveY = this.startPoint.y * 1 + moveY * 1
if (moveX >= this.width) {
this.move.x = this.width
} else if (moveX <= 0) {
this.move.x = 0
} else {
this.move.x = moveX
}
},
touchend (e) {
this.setTransition(true)