仿QQ删除聊天和删除好友
效果图:
(1) Friend-page.vue文件相关代码
<template name="friendPage">
<view class="fl-container">
<view class="feature-num" v-if="friend_num">{{friend_num}}位好友</view>
<view class="feature-num" v-else>暂无好友,快去互相关注添加好友吧</view>
<view v-for="(item,index) in all_friend" :key="index">
<friendList :content="item" :index="index" @close='colseLeftside' @closeElseParent="closeOtherall"></friendList>
</view>
</view>
</template>
<script>
let _this=null,token=null;
import getData from '../../../../util/common.js'; //导入网络请求封装接口
import friendList from './Friend-list/Friend-list.vue'; //导入单个好友列表组件
export default {
data: function() {
return {
allFriends:[],
}
},
components: {friendList},
computed:{
friend_num:function(){
if(_this.allFriends.length){
let num=0;
_this.allFriends.map((item,index)=>{
num+=item.list.length
});
return num
}else{
return 0
}
}
},
methods: {
//获取所有好友列表
获取每个列表中的好友
getFriendLists(){
getData("api/user/getMyFriend",{token},0,0,function(data){
console.log(data);
_this.allFriends=data;
})
},
// 关闭其他列表左滑状态
如:在第一个列表中有左滑,在其他又左滑一个好友时,会关闭第一个列表中好友左滑的效果
colseLeftside(){
this.allFriends.map(function(item,index){
item.list.map(function(i,n){
i.txtStyle=''
})
})
},
//关闭其他所有单个的左滑状态
closeOtherall(num){
this.allFriends.map(function(item,index){
if(index!=num){
item.list.map(function(i,n){
i.txtStyle=''
})
}
})
},
//删除好友
deleteFriend(id,num){
getData("api/user/delFollow",{token,fid:id},0,0,function(data){
_this.allFriends.map((item,index)=>{
item.list.map((i,n)=>{
if(i.id==id){
_this.allFriends[index].list.splice(n,1);
}
})
})
_this.$nextTick(function(){
_this.$forceUpdate();//等data中数据更新完后强制刷新数据
})
})
}
},
onLoad(){
_this=this;
token = uni.getStorageSync("token");
},
}
(2)Friend-list 文件相关代码
<template>
<view>
<view class='classify-box' @click.stop="openList">
<view>
<image v-show="!isOpen" class="icon-s" src="/static/img/icon/icon_20.png"></image>
<image v-show="isOpen" class="icon-s" src="/static/img/icon/icon_19.png"></image>
</view>
<view class='classify'>
<text>{{content.title}}</text>
</view>
</view>
<view v-if='isOpen'>
<view v-if="content.list.length">
<view v-for="(item,index) in content.list" :key="index">
<Friend :content="item" :index="index" @moveS="startMove" @moveZ="move"
@moveE="endMove" @closeElse="closeOther" @deleteF="deleteFriend"></Friend>
</view>
</view>
</view>
</view>
</template>
<script>
import Friend from '../Friend/Friend.vue'//导入单个好友组件
export default {
name: "Friend_list",
props:["content","index"],
data: function() {
return {
isOpen: false,
}
},
components: { Friend },
methods: {
// 打开或关闭好友列表
openList() {
this.$emit("close")
this.isOpen = !this.isOpen;
},
//任一个左滑时关闭其他左滑状态
closeOther(){
this.$emit("closeElseParent",this.index)
},
//开始移动
startMove(num) {
let _this = this;
_this.content.list.map(function(item, index) {
if (num != index) {
_this.content.list[index].txtStyle = ''
}
})
},
//滑动过程中。
move(obj) {
this.content.list[obj.num].txtStyle = obj.str//txtStyle即为滑动块的定位位置,特别重要
},
//滑动结束
endMove(obj) {
this.content.list[obj.num].txtStyle = obj.str
},
//删除好友
deleteFriend(id){
this.$emit("deleteP",id,this.index)
}
}
}
</script>
注: txtStyle为滑动块定位位置,添加到动态style样式上,左滑的位置由它控制,必不可少
(3) Friend 文件相关代码
<template>
<view class="con">
<view class="member-list-li" @click="lookDetail(content.id)">
<view class="touch-list list-touch" @touchstart="touchS" @touchmove="touchM" @touchend="touchE" :data-index="index" :style="content.txtStyle">
<view>
<image class="img" :src="content.avatar"></image>
</view>
<view class="member-box ">
<view class="row1">
<view class='left'>
<view class="name">{{content.name}}</view>
<image class='icon' v-if="content.isvip=='1'" src='/static/img/icon/canmai.png'>
</image>
</view>
<view v-show='isHide' class="chat">
<text @click.stop="toChat(content.id)">聊天</text>
</view>
</view>
<view class="row2">
<text class='company'>{{company}}</text>
<text class="position">{{content.position}}</text>
</view>
</view>
</view>
<view class="touch-list list-delete" :data-userid="content.id" @click.stop="deleteMember(content.id)">
<text>删除</text>
</view>
</view>
</view>
</template>
<script>
export default {
props: ['content', "index"],
data: function() {
return {
delBtnWidth: 68, //删除按钮宽度单位(rpx)
startX: '',
}
},
computed: {
company: function() {
const length1 = this.content.company.length;
const length2 = this.content.position.length;
if (length1 + length2 > 17) {
return this.content.company.substring(0, (16 - length2)) + '...'
} else {
return this.content.company
}
},
isHide:function(){
if(this.content.txtStyle==''||this.content.txtStyle=="left:0px"){
return true
}else{
return false
}
}
},
methods: {
touchS: function(e) {
if (e.touches.length == 1) {
//设置触摸起始点水平方向位置
this.startX = e.touches[0].clientX
this.$emit("moveS", this.index);
this.$emit("closeElse")
}
},
touchM: function(e) {
if (e.touches.length == 1) {
//手指移动时水平方向位置
var moveX = e.touches[0].clientX;
//手指起始点位置与移动期间的差值
var disX = this.startX - moveX;
var delBtnWidth = this.delBtnWidth;
var txtStyle = "";
if (disX == 0 || disX < 0) { //如果移动距离小于等于0,说明向右滑动,文本层位置不变
txtStyle = "left:0px";
} else if (disX > 0) { //移动距离大于0,文本层left值等于手指移动距离
txtStyle = "left:-" + disX + "px";
if (disX >= delBtnWidth) {
//控制手指移动距离最大值为删除按钮的宽度
txtStyle = "left:-" + delBtnWidth + "px";
}
}
//获取手指触摸的是哪一项
var index = Number(e.currentTarget.dataset.index);
this.$emit("moveZ", {
num: index,
str: txtStyle
})
}
},
touchE: function(e) {
if (e.changedTouches.length == 1) {
//手指移动结束后水平位置
var endX = e.changedTouches[0].clientX;
//触摸开始与结束,手指移动的距离
var disX = this.startX - endX;
var delBtnWidth = this.delBtnWidth;
//如果距离小于删除按钮的1/2,不显示删除按钮
var txtStyle = disX > delBtnWidth / 2 ? "left:-" + delBtnWidth + "px" : "left:0px";
//获取手指触摸的是哪一项
var index = Number(e.currentTarget.dataset.index);
this.$emit("moveE", {
num: index,
str: txtStyle
});
}
},
//查看好友详情
lookDetail(id){
uni.navigateTo({
url:"/pages/tabbar/tabbar-3/Friend-page/Friend-detatil/Friend-detatil?id="+id
})
},
//删除好友
deleteMember: function(id) {
this.$emit("deleteF",id)
},
// 和好友聊天
toChat(id){
uni.navigateTo({
url: '/pages/HM-chat/HM-chat?id='+id
});
}
},
}
</script>
总结:该方法主要是根据固定位置来达到左滑效果,样式中需要position:fixed做定位;故html结构的style会是动态数据,利用@touchstart、@touchmove、@touchend来监听结构在视图区域的位置,然后动态改变结构style中left值