feat: 在留言板组件中添加模态弹窗功能,优化滑动操作和删除确认逻辑
This commit is contained in:
parent
48c94b0905
commit
e194091873
|
@ -2,16 +2,19 @@
|
|||
<view class="message-board-component">
|
||||
<!-- 一个列表一个swipe-action容器更符合官方推荐用法 -->
|
||||
<view v-for="(item, index) in answerList" :key="item.id">
|
||||
<uni-swipe-action>
|
||||
<uni-swipe-action ref="swipeActionRef">
|
||||
<!-- :right-options="swipeOptions" -->
|
||||
<uni-swipe-action-item
|
||||
:disabled="!canSwipe"
|
||||
:threshold="0.3"
|
||||
:auto-close="false"
|
||||
@change="(e) => handleSwipeChange(e, index)"
|
||||
@change="handleSwipeChange($event, index)"
|
||||
>
|
||||
<template #right>
|
||||
<view class="right-btn-box" @click.stop="handleSwipeClick(item, index, e)">
|
||||
<template v-slot:right>
|
||||
<view
|
||||
class="right-btn-box"
|
||||
@touchend.stop="handleSwipeClick(item, index)"
|
||||
>
|
||||
<image
|
||||
class="right-btn"
|
||||
src="/static/common/images/icon_delete.png"
|
||||
|
@ -76,7 +79,11 @@
|
|||
|
||||
<!-- 回复按钮-老师 -->
|
||||
<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
|
||||
class="reply-btn-icon"
|
||||
src="/static/common/images/icon_reply.png"
|
||||
|
@ -104,6 +111,24 @@
|
|||
</uni-swipe-action-item>
|
||||
</uni-swipe-action>
|
||||
</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>
|
||||
</template>
|
||||
|
||||
|
@ -134,8 +159,16 @@ export default {
|
|||
data() {
|
||||
return {
|
||||
AvatarDefault, // 默认头像
|
||||
currentItem: {}, // 当前操作的item
|
||||
currentIndex: 0, // 当前操作的item索引
|
||||
openedItems: {}, // 记录每个项目的滑动状态
|
||||
isWebMode: false, // 是否是web模式
|
||||
|
||||
// 模态弹窗
|
||||
modalShow: false,
|
||||
content: "确定要撤回该留言吗?",
|
||||
modalOpenTime: 0,
|
||||
preventCloseOnce: false, // 添加防误触标记
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
|
@ -147,9 +180,20 @@ export default {
|
|||
console.log("isWebMode", this.isWebMode);
|
||||
},
|
||||
methods: {
|
||||
// 监听滑动状态变化
|
||||
handleSwipeChange(e, index) {
|
||||
// 使用Vue的响应式更新方法来更新对象
|
||||
this.$set(this.openedItems, index, e);
|
||||
// console.log("滑动状态", this.openedItems);
|
||||
},
|
||||
// 处理左滑按钮点击
|
||||
handleSwipeClick(item, index, e) {
|
||||
console.log("按钮点击", item, index, e);
|
||||
handleSwipeClick(item, index) {
|
||||
// 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模式点击
|
||||
|
@ -157,11 +201,38 @@ export default {
|
|||
console.log("web模式点击", item);
|
||||
},
|
||||
|
||||
// 监听滑动状态变化
|
||||
handleSwipeChange(isOpened, index) {
|
||||
// 使用Vue的响应式更新方法来更新对象
|
||||
this.$set(this.openedItems, index, isOpened);
|
||||
console.log("滑动状态", this.openedItems);
|
||||
// 处理回复按钮点击
|
||||
handleReplyClick(item) {
|
||||
if (item.isReply) {
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
justify-content: center;
|
||||
border-radius: 0 16rpx 16rpx 0;
|
||||
border: 1px solid #fff; /* 防止初始状态下出现红线 */
|
||||
margin-bottom: 32rpx;
|
||||
.right-btn {
|
||||
width: 32rpx;
|
||||
|
@ -302,6 +374,10 @@ export default {
|
|||
width: 100%;
|
||||
margin-top: 28rpx;
|
||||
|
||||
.uni-btn-reset::after {
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
.reply-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
@ -320,6 +396,10 @@ export default {
|
|||
margin-right: 12rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.disabled-reply {
|
||||
background: #cccccc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -343,4 +423,51 @@ export default {
|
|||
height: 32rpx;
|
||||
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>
|
||||
|
|
|
@ -21,8 +21,14 @@
|
|||
<!-- 内容区域包装器 -->
|
||||
<view class="content-wrapper">
|
||||
<!-- 问答列表组件 -->
|
||||
<message-board :answerList="answerList"></message-board>
|
||||
<message-board
|
||||
:answerList="answerList"
|
||||
@delete="handleDelete"
|
||||
></message-board>
|
||||
</view>
|
||||
|
||||
<!-- 提示 -->
|
||||
<u-toast ref="uToast" />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
|
@ -91,6 +97,17 @@ export default {
|
|||
// 根据索引设置activeTab值
|
||||
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>
|
||||
|
|
Loading…
Reference in New Issue