feat: 在留言板组件中添加模态弹窗功能,优化滑动操作和删除确认逻辑
This commit is contained in:
parent
48c94b0905
commit
e194091873
|
@ -2,16 +2,19 @@
|
||||||
<view class="message-board-component">
|
<view class="message-board-component">
|
||||||
<!-- 一个列表一个swipe-action容器更符合官方推荐用法 -->
|
<!-- 一个列表一个swipe-action容器更符合官方推荐用法 -->
|
||||||
<view v-for="(item, index) in answerList" :key="item.id">
|
<view v-for="(item, index) in answerList" :key="item.id">
|
||||||
<uni-swipe-action>
|
<uni-swipe-action ref="swipeActionRef">
|
||||||
<!-- :right-options="swipeOptions" -->
|
<!-- :right-options="swipeOptions" -->
|
||||||
<uni-swipe-action-item
|
<uni-swipe-action-item
|
||||||
:disabled="!canSwipe"
|
:disabled="!canSwipe"
|
||||||
:threshold="0.3"
|
:threshold="0.3"
|
||||||
:auto-close="false"
|
:auto-close="false"
|
||||||
@change="(e) => handleSwipeChange(e, index)"
|
@change="handleSwipeChange($event, index)"
|
||||||
|
>
|
||||||
|
<template v-slot:right>
|
||||||
|
<view
|
||||||
|
class="right-btn-box"
|
||||||
|
@touchend.stop="handleSwipeClick(item, index)"
|
||||||
>
|
>
|
||||||
<template #right>
|
|
||||||
<view class="right-btn-box" @click.stop="handleSwipeClick(item, index, e)">
|
|
||||||
<image
|
<image
|
||||||
class="right-btn"
|
class="right-btn"
|
||||||
src="/static/common/images/icon_delete.png"
|
src="/static/common/images/icon_delete.png"
|
||||||
|
@ -76,7 +79,11 @@
|
||||||
|
|
||||||
<!-- 回复按钮-老师 -->
|
<!-- 回复按钮-老师 -->
|
||||||
<view class="reply-btn-box" v-if="isTeacher">
|
<view class="reply-btn-box" v-if="isTeacher">
|
||||||
<button class="reply-btn">
|
<button
|
||||||
|
class="reply-btn uni-btn-reset"
|
||||||
|
:class="{ 'disabled-reply': item.isReply }"
|
||||||
|
@click.stop="handleReplyClick(item)"
|
||||||
|
>
|
||||||
<image
|
<image
|
||||||
class="reply-btn-icon"
|
class="reply-btn-icon"
|
||||||
src="/static/common/images/icon_reply.png"
|
src="/static/common/images/icon_reply.png"
|
||||||
|
@ -104,6 +111,24 @@
|
||||||
</uni-swipe-action-item>
|
</uni-swipe-action-item>
|
||||||
</uni-swipe-action>
|
</uni-swipe-action>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
|
<!-- 模态弹窗 -->
|
||||||
|
<u-popup
|
||||||
|
v-model="modalShow"
|
||||||
|
mode="center"
|
||||||
|
width="70%"
|
||||||
|
border-radius="16"
|
||||||
|
:mask-close-able="false"
|
||||||
|
>
|
||||||
|
<view class="custom-modal">
|
||||||
|
<view class="modal-title">提示</view>
|
||||||
|
<view class="modal-content">{{ content }}</view>
|
||||||
|
<view class="modal-footer">
|
||||||
|
<view class="modal-btn cancel" @click="handleCancel">取消</view>
|
||||||
|
<view class="modal-btn confirm" @click="handleConfirm">确认</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</u-popup>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -134,8 +159,16 @@ export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
AvatarDefault, // 默认头像
|
AvatarDefault, // 默认头像
|
||||||
|
currentItem: {}, // 当前操作的item
|
||||||
|
currentIndex: 0, // 当前操作的item索引
|
||||||
openedItems: {}, // 记录每个项目的滑动状态
|
openedItems: {}, // 记录每个项目的滑动状态
|
||||||
isWebMode: false, // 是否是web模式
|
isWebMode: false, // 是否是web模式
|
||||||
|
|
||||||
|
// 模态弹窗
|
||||||
|
modalShow: false,
|
||||||
|
content: "确定要撤回该留言吗?",
|
||||||
|
modalOpenTime: 0,
|
||||||
|
preventCloseOnce: false, // 添加防误触标记
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
@ -147,9 +180,20 @@ export default {
|
||||||
console.log("isWebMode", this.isWebMode);
|
console.log("isWebMode", this.isWebMode);
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
// 监听滑动状态变化
|
||||||
|
handleSwipeChange(e, index) {
|
||||||
|
// 使用Vue的响应式更新方法来更新对象
|
||||||
|
this.$set(this.openedItems, index, e);
|
||||||
|
// console.log("滑动状态", this.openedItems);
|
||||||
|
},
|
||||||
// 处理左滑按钮点击
|
// 处理左滑按钮点击
|
||||||
handleSwipeClick(item, index, e) {
|
handleSwipeClick(item, index) {
|
||||||
console.log("按钮点击", item, index, e);
|
// console.log("swipeClick", item, index);
|
||||||
|
// console.log("swipeActionRef", this.$refs.swipeActionRef);
|
||||||
|
this.currentItem = item;
|
||||||
|
this.currentIndex = index;
|
||||||
|
this.modalShow = true;
|
||||||
|
this.modalOpenTime = Date.now(); // 记录模态框打开时间
|
||||||
},
|
},
|
||||||
|
|
||||||
// 处理web模式点击
|
// 处理web模式点击
|
||||||
|
@ -157,11 +201,38 @@ export default {
|
||||||
console.log("web模式点击", item);
|
console.log("web模式点击", item);
|
||||||
},
|
},
|
||||||
|
|
||||||
// 监听滑动状态变化
|
// 处理回复按钮点击
|
||||||
handleSwipeChange(isOpened, index) {
|
handleReplyClick(item) {
|
||||||
// 使用Vue的响应式更新方法来更新对象
|
if (item.isReply) {
|
||||||
this.$set(this.openedItems, index, isOpened);
|
return;
|
||||||
console.log("滑动状态", this.openedItems);
|
}
|
||||||
|
|
||||||
|
this.$emit("reply", item);
|
||||||
|
},
|
||||||
|
|
||||||
|
// 处理取消按钮点击
|
||||||
|
handleCancel() {
|
||||||
|
this.modalShow = false;
|
||||||
|
},
|
||||||
|
|
||||||
|
// 处理确认按钮点击
|
||||||
|
handleConfirm() {
|
||||||
|
// 检查是否是快速点击(防止误触)
|
||||||
|
if (this.modalOpenTime && Date.now() - this.modalOpenTime < 300) {
|
||||||
|
console.log("防止误触,请重新点击");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 发送删除事件,并传递回调函数
|
||||||
|
this.$emit("delete", this.currentItem, (success) => {
|
||||||
|
// 只有当操作成功时才关闭模态框
|
||||||
|
console.log("callback success", success);
|
||||||
|
|
||||||
|
if (success) {
|
||||||
|
this.$refs.swipeActionRef[this.currentIndex].closeAll();
|
||||||
|
this.modalShow = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -180,6 +251,7 @@ export default {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
border-radius: 0 16rpx 16rpx 0;
|
border-radius: 0 16rpx 16rpx 0;
|
||||||
|
border: 1px solid #fff; /* 防止初始状态下出现红线 */
|
||||||
margin-bottom: 32rpx;
|
margin-bottom: 32rpx;
|
||||||
.right-btn {
|
.right-btn {
|
||||||
width: 32rpx;
|
width: 32rpx;
|
||||||
|
@ -302,6 +374,10 @@ export default {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin-top: 28rpx;
|
margin-top: 28rpx;
|
||||||
|
|
||||||
|
.uni-btn-reset::after {
|
||||||
|
border: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
.reply-btn {
|
.reply-btn {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
@ -320,6 +396,10 @@ export default {
|
||||||
margin-right: 12rpx;
|
margin-right: 12rpx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.disabled-reply {
|
||||||
|
background: #cccccc;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -343,4 +423,51 @@ export default {
|
||||||
height: 32rpx;
|
height: 32rpx;
|
||||||
margin-right: 8rpx;
|
margin-right: 8rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.custom-modal {
|
||||||
|
background-color: #fff;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
.modal-title {
|
||||||
|
font-size: 32rpx;
|
||||||
|
font-weight: 500;
|
||||||
|
text-align: center;
|
||||||
|
padding: 30rpx 0;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-content {
|
||||||
|
padding: 30rpx;
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #666;
|
||||||
|
text-align: center;
|
||||||
|
min-height: 80rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-footer {
|
||||||
|
display: flex;
|
||||||
|
border-top: 1px solid #eee;
|
||||||
|
|
||||||
|
.modal-btn {
|
||||||
|
flex: 1;
|
||||||
|
height: 90rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 30rpx;
|
||||||
|
|
||||||
|
&.cancel {
|
||||||
|
color: #666;
|
||||||
|
border-right: 1px solid #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.confirm {
|
||||||
|
color: #4f6aff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -21,8 +21,14 @@
|
||||||
<!-- 内容区域包装器 -->
|
<!-- 内容区域包装器 -->
|
||||||
<view class="content-wrapper">
|
<view class="content-wrapper">
|
||||||
<!-- 问答列表组件 -->
|
<!-- 问答列表组件 -->
|
||||||
<message-board :answerList="answerList"></message-board>
|
<message-board
|
||||||
|
:answerList="answerList"
|
||||||
|
@delete="handleDelete"
|
||||||
|
></message-board>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
|
<!-- 提示 -->
|
||||||
|
<u-toast ref="uToast" />
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -91,6 +97,17 @@ export default {
|
||||||
// 根据索引设置activeTab值
|
// 根据索引设置activeTab值
|
||||||
this.activeTab = index === 0 ? "unread" : "replied";
|
this.activeTab = index === 0 ? "unread" : "replied";
|
||||||
},
|
},
|
||||||
|
handleDelete(item, callback) {
|
||||||
|
console.log("handleDelete", item);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
this.$refs.uToast.show({
|
||||||
|
title: "撤回成功",
|
||||||
|
type: "success",
|
||||||
|
});
|
||||||
|
callback(true);
|
||||||
|
}, 1500);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
Loading…
Reference in New Issue