more-button.vue
3.24 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
<template>
<view class="more-actions">
<!-- 点击按钮 -->
<view class="trigger-btn" @click="toggleMenu" hover-class="btn-hover">
<uni-icons type="more" size="28" color="#999" />
</view>
<!-- 手写下拉菜单 -->
<view class="dropdown-menu" :class="{ show: showMenu }">
<view class="menu-item" @click="handleNote">文字备注</view>
<view class="menu-item" @click="handleVideoNote">视频备注</view>
<view class="menu-item" @click="handleRest">组间休息</view>
<view class="menu-item" @click="handleReplace">动作替换</view>
<view class="menu-item danger" @click="handleDelete">删除动作</view>
</view>
</view>
</template>
<script setup>
import { ref, onMounted, onUnmounted } from 'vue'
const props = defineProps({
exerciseId: [String, Number],
})
const showMenu = ref(false)
// 切换菜单显示
const toggleMenu = (e) => {
e.stopPropagation() // 关键:阻止事件冒泡,防止document事件触发
showMenu.value = !showMenu.value
}
// 点击页面其他地方关闭菜单
const closeMenu = (e) => {
showMenu.value = false
}
// 注册/移除点击事件(修复:用uni的API,不要用原生document)
onMounted(() => {
// uni-app 小程序不支持 document,用 uni.$on 或者自定义事件
// 这里改用更安全的方式:页面点击时关闭
uni.$on('page-click', closeMenu)
})
onUnmounted(() => {
uni.$off('page-click', closeMenu)
})
// 菜单事件
const handleNote = () => {
uni.showToast({ title: '文字备注', icon: 'none' })
showMenu.value = false
}
const handleVideoNote = () => {
uni.showToast({ title: '视频备注', icon: 'none' })
showMenu.value = false
}
const handleRest = () => {
uni.showToast({ title: '组间休息', icon: 'none' })
showMenu.value = false
}
const handleReplace = () => {
uni.showToast({ title: '动作替换', icon: 'none' })
showMenu.value = false
}
const handleDelete = () => {
uni.showModal({
title: '确认删除',
content: '确定要删除该动作吗?',
success: (res) => {
if (res.confirm) {
uni.showToast({ title: '已删除' })
}
showMenu.value = false // 不管确认还是取消,都关闭菜单
}
})
}
</script>
<style scoped lang="scss">
.more-actions {
position: relative;
display: inline-block;
margin-left: 10rpx;
z-index: 1;
}
.trigger-btn {
width: 60rpx;
height: 60rpx;
border-radius: 50%;
border: 1rpx solid #dcdcdc;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
}
.btn-hover {
background-color: #eee;
}
/* 下拉菜单核心样式 */
.dropdown-menu {
position: absolute;
top: 70rpx;
right: 0;
background: #fff;
border-radius: 10rpx;
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.15);
min-width: 200rpx;
display: none;
overflow: hidden;
}
.dropdown-menu.show {
display: block;
}
.menu-item {
padding: 24rpx 32rpx;
font-size: 28rpx;
color: #333;
border-bottom: 1rpx solid #f0f0f0;
}
.menu-item:last-child {
border-bottom: none;
}
.menu-item.danger {
color: #ff4444;
}
</style>