mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-04-06 03:57:59 +08:00
CellSwipe: code review
This commit is contained in:
parent
c7b96bd8e0
commit
c5474b2106
@ -1,15 +1,19 @@
|
||||
<template>
|
||||
<div v-clickoutside:touchstart="swipeMove" @click="swipeMove()" @touchstart="startDrag" @touchmove="onDrag" @touchend="endDrag" class="van-cell-swipe" ref="cell">
|
||||
<div class="van-cell-wrapper">
|
||||
<slot>单元格内容</slot>
|
||||
</div>
|
||||
<div class="van-cell-left">
|
||||
<div ref="left">
|
||||
<div
|
||||
v-clickoutside:touchstart="swipeMove"
|
||||
class="van-cell-swipe"
|
||||
@click="swipeMove()"
|
||||
@touchstart="startDrag"
|
||||
@touchmove="onDrag"
|
||||
@touchend="endDrag"
|
||||
@touchcancel="endDrag"
|
||||
>
|
||||
<div class="van-cell-swipe__wrapper" :style="wrapperStyle" @transitionend="swipe = false">
|
||||
<div class="van-cell-swipe__left" v-if="leftWidth">
|
||||
<slot name="left"></slot>
|
||||
</div>
|
||||
</div>
|
||||
<div class="van-cell-right">
|
||||
<div ref="right">
|
||||
<slot></slot>
|
||||
<div class="van-cell-swipe__right" v-if="rightWidth">
|
||||
<slot name="right"></slot>
|
||||
</div>
|
||||
</div>
|
||||
@ -17,112 +21,101 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { once } from '../utils/dom';
|
||||
import Clickoutside from '../utils/clickoutside';
|
||||
|
||||
export default {
|
||||
name: 'van-cell-swipe',
|
||||
|
||||
props: {
|
||||
'leftWidth': { type: Number, default: 0 },
|
||||
'rightWidth': { type: Number, default: 0 }
|
||||
},
|
||||
directives: { Clickoutside },
|
||||
data() {
|
||||
return {
|
||||
start: { x: 0, y: 0 }
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
leftDefaultTransform() {
|
||||
return this.translate3d(-this.leftWidth - 1);
|
||||
leftWidth: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
rightDefaultTransform() {
|
||||
return this.translate3d(this.rightWidth);
|
||||
rightWidth: {
|
||||
type: Number,
|
||||
default: 0
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.wrap = this.$refs.cell.querySelector('.van-cell-wrapper');
|
||||
this.leftElm = this.$refs.left;
|
||||
this.leftWrapElm = this.leftElm.parentNode;
|
||||
this.leftWrapElm.style.webkitTransform = this.leftDefaultTransform;
|
||||
|
||||
this.rightElm = this.$refs.right;
|
||||
this.rightWrapElm = this.rightElm.parentNode;
|
||||
this.rightWrapElm.style.webkitTransform = this.rightDefaultTransform;
|
||||
directives: {
|
||||
Clickoutside
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
offset: 0
|
||||
};
|
||||
},
|
||||
|
||||
computed: {
|
||||
wrapperStyle() {
|
||||
return {
|
||||
transform: `translate3d(${this.offset}px, 0, 0)`
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
resetSwipeStatus() {
|
||||
this.swiping = false; // 是否正在拖动
|
||||
this.opened = true; // 记录是否滑动左右 或者 注册
|
||||
this.offsetLeft = 0; // 记录单次拖动的拖动距离
|
||||
},
|
||||
translate3d(offset) {
|
||||
return `translate3d(${offset}px, 0, 0)`;
|
||||
},
|
||||
|
||||
swipeMove(offset = 0) {
|
||||
this.wrap.style.webkitTransform = this.translate3d(offset);
|
||||
this.rightWrapElm.style.webkitTransform = this.translate3d(this.rightWidth + offset);
|
||||
this.leftWrapElm.style.webkitTransform = this.translate3d(-this.leftWidth + offset);
|
||||
this.offset = offset;
|
||||
offset && (this.swiping = true);
|
||||
},
|
||||
|
||||
swipeLeaveTransition(direction) {
|
||||
setTimeout(() => {
|
||||
this.swipeLeave = true;
|
||||
// left
|
||||
if (direction > 0 && -this.offsetLeft > this.rightWidth * 0.4 && this.rightWidth > 0) {
|
||||
this.swipeMove(-this.rightWidth);
|
||||
this.resetSwipeStatus();
|
||||
return;
|
||||
// right
|
||||
} else if (direction < 0 && this.offsetLeft > this.leftWidth * 0.4 && this.leftWidth > 0) {
|
||||
this.swipeMove(this.leftWidth);
|
||||
this.resetSwipeStatus();
|
||||
return;
|
||||
} else {
|
||||
this.swipeMove(0);
|
||||
once(this.wrap, 'webkitTransitionEnd', () => {
|
||||
this.wrap.style.webkitTransform = '';
|
||||
this.rightWrapElm.style.webkitTransform = this.rightDefaultTransform;
|
||||
this.leftWrapElm.style.webkitTransform = this.leftDefaultTransform;
|
||||
this.swipeLeave = false;
|
||||
this.swiping = false;
|
||||
});
|
||||
}
|
||||
}, 0);
|
||||
const { offset, leftWidth, rightWidth } = this;
|
||||
// right
|
||||
if (direction > 0 && -offset > rightWidth * 0.4 && rightWidth > 0) {
|
||||
this.swipeMove(-rightWidth);
|
||||
this.resetSwipeStatus();
|
||||
}
|
||||
// left
|
||||
else if (direction < 0 && offset >leftWidth * 0.4 && leftWidth > 0) {
|
||||
this.swipeMove(leftWidth);
|
||||
this.resetSwipeStatus();
|
||||
} else {
|
||||
this.swipeMove();
|
||||
}
|
||||
},
|
||||
startDrag(evt) {
|
||||
evt = evt.changedTouches ? evt.changedTouches[0] : evt;
|
||||
this.dragging = true;
|
||||
this.start.x = evt.pageX;
|
||||
this.start.y = evt.pageY;
|
||||
|
||||
startDrag(event) {
|
||||
this.startX = event.changedTouches[0].pageX;
|
||||
this.startY = event.changedTouches[0].pageY;
|
||||
},
|
||||
onDrag(evt) {
|
||||
|
||||
onDrag(event) {
|
||||
if (this.opened) {
|
||||
!this.swiping && this.swipeMove(0);
|
||||
!this.swiping && this.swipeMove();
|
||||
this.opened = false;
|
||||
return;
|
||||
}
|
||||
if (!this.dragging) return;
|
||||
let swiping;
|
||||
const e = evt.changedTouches ? evt.changedTouches[0] : evt;
|
||||
const offsetTop = e.pageY - this.start.y;
|
||||
const offsetLeft = this.offsetLeft = e.pageX - this.start.x;
|
||||
|
||||
const offsetTop = event.changedTouches[0].pageY - this.startY;
|
||||
const offsetLeft = event.changedTouches[0].pageX - this.startX;
|
||||
if ((offsetLeft < 0 && -offsetLeft > this.rightWidth) ||
|
||||
(offsetLeft > 0 && offsetLeft > this.leftWidth) ||
|
||||
(offsetLeft > 0 && !this.leftWidth) ||
|
||||
(offsetLeft < 0 && !this.rightWidth)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const y = Math.abs(offsetTop);
|
||||
const x = Math.abs(offsetLeft);
|
||||
swiping = !(x < 5 || (x >= 5 && y >= x * 1.73));
|
||||
if (!swiping) return;
|
||||
evt.preventDefault();
|
||||
this.swipeMove(offsetLeft);
|
||||
const swiping = !(x < 5 || (x >= 5 && y >= x * 1.73));
|
||||
if (swiping) {
|
||||
event.preventDefault();
|
||||
this.swipeMove(offsetLeft);
|
||||
};
|
||||
},
|
||||
|
||||
endDrag() {
|
||||
if (!this.swiping) return;
|
||||
this.swipeLeaveTransition(this.offsetLeft > 0 ? -1 : 1);
|
||||
if (this.swiping) {
|
||||
this.swipeLeaveTransition(this.offset > 0 ? -1 : 1);
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -1,29 +1,26 @@
|
||||
.van-cell {
|
||||
&-swipe {
|
||||
position: relative;
|
||||
min-height: 48px;
|
||||
overflow: hidden;
|
||||
.van-cell-swipe {
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
|
||||
.van-cell-wrapper,
|
||||
.van-cell-left,
|
||||
.van-cell-right {
|
||||
transition: transform 150ms ease-in-out;
|
||||
}
|
||||
&__wrapper,
|
||||
&__left,
|
||||
&__right {
|
||||
transition: transform .15s ease-in-out;
|
||||
}
|
||||
|
||||
&-left,
|
||||
&-right {
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
&__left,
|
||||
&__right {
|
||||
top: 0;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
&-left {
|
||||
&__left {
|
||||
left: 0;
|
||||
transform: translate3d(-100%, 0, 0);
|
||||
}
|
||||
|
||||
&-right {
|
||||
&__right {
|
||||
right: 0;
|
||||
transform: translate3d(100%, 0, 0);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user