MessageItem.vue
<template>
<div
v-if="visiual"
ref="messageitem"
class="messageitem"
@touchstart="touchStart"
@touchmove="touchMove"
@touchend="touchEnd"
>
<div class="normal">{{ data }}</div>
<div class="del" @click="deleteItem">删除</div>
</div>
</template>
↓
export default {
name: "MessageItem",
data() {
return {
visiual: true,
node: null,
startX: 0,
endx: 0,
distanceX: 0,
deleteWidth: -80, // 删除按键的宽度相反数
freezeDisX: 0 // 记录当手指在屏幕上首次 touch 时候元素的位移量
};
},
props: ["data", "index"],
mounted() {
this.node = this.$refs["messageitem"];
},
methods: {
// 初始化操作
initStart(e) {
const currentNodeStyle = this.node.style.transform;
this.freezeDisX = currentNodeStyle
? this.transToNumber(currentNodeStyle)
: 0;
this.startX = e.targetTouches[0].pageX;
},
// 滑动开始
touchStart(e) {
this.initStart(e);
},
// 滑动中
touchMove(e) {
this.endX = e.targetTouches[0].pageX;
this.distanceX = this.endX - this.startX; // 负数表示向左滑动 正数表示向右滑动
let computedDistance = this.distanceX + this.freezeDisX;
// 矫正检验 防止滑动过偏
if (computedDistance <= this.deleteWidth) {
this.initStart(e); // 手指滑动过偏矫正 可以注释掉
computedDistance = this.deleteWidth;
} else if (computedDistance >= 0) {
this.initStart(e); // 手指滑动过偏矫正 可以注释掉
computedDistance = 0;
}
this.node.style.transform = `translateX(${computedDistance}px)`;
},
// 滑动结束
touchEnd(e) {
// 滑动结束后检验移动距离 让滑动块归位到两端
const finalCheckDistance = this.transToNumber(this.node.style.transform);
const finalRealDistance =
finalCheckDistance < this.deleteWidth / 2 ? this.deleteWidth : 0;
this.node.style.transform = `translateX(${finalRealDistance}px)`;
},
// 取出 transform 里面的偏移量
transToNumber(string) {
// return Number(string.replace(/translateX\(/gm, "").replace(/px\)/gm, ""));
return string ? Number(string.match(/-?\d+/gm)[0]) : 0;
},
// 删除操作
deleteItem() {
this.visiual = false;
console.log(this.index);
}
}
};
↓
.messageitem {
position: relative;
height: 60px;
line-height: 60px;
border-left: 4px solid #2f8432;
background-color: #c9ffcc;
margin-bottom: 20px;
font-size: 1.5em;
user-select: none;
}
.del {
width: 80px;
position: absolute;
top: 0;
color: #fff;
background-color: #d26861;
right: -80px;
}
Message.vue
<template>
<div id="message" v-scroll="loadMore">
<MessageItem v-for="(item, index) in arr" :data="item" :index="index" :key="index"></MessageItem>
<ScrollLoading v-if="isLoading"></ScrollLoading>
<p v-if="dataIsEmpty">数据没有更多了。。。</p>
</div>
</template>
↓
import { tes } from "@/api/user";
import MessageItem from './MessageItem';
export default {
name: "Message",
components: { MessageItem },
data() {
return {
isLoading: false,
dataIsEmpty: false,
pageNum: 1,
arr: []
};
},
mounted() {
this.loadMore();
},
methods: {
loadMore() {
this.isLoading = true;
return new Promise((resolve, reject) => {
tes({
pageSize: 3,
pageNum: this.pageNum++
}).then(res => {
this.isLoading = false;
let length = res.data.result.records.length;
let newArr = res.data.result.records.map(item => item.goodsName);
this.arr = [...this.arr, ...newArr];
resolve(length);
this.dataIsEmpty = !Boolean(length);
});
});
}
}
};
网友评论