hookehuyr

feat(PointsCollector): 重构积分收集组件并添加一键收取功能

- 重构积分收集组件布局和样式
- 实现一键收取功能并优化收集动画
- 移除冗余代码并提升性能
- 添加组件高度可配置属性
1 <template> 1 <template>
2 - <view class="points-collector"> 2 + <view class="points-collector" :style="{ height: height }">
3 <!-- 中心圆形显示总积分 --> 3 <!-- 中心圆形显示总积分 -->
4 <view class="center-circle"> 4 <view class="center-circle">
5 <view class="total-points"> 5 <view class="total-points">
6 - <text class="points-number">{{ animatedTotalPoints }}</text> 6 + <text class="points-number">{{ animatedTotalPoints }}</text>
7 - <text class="points-label">总积分</text> 7 + <text class="points-label">去兑换</text>
8 </view> 8 </view>
9 </view> 9 </view>
10 10
11 <!-- 周围漂浮的小圆圈 --> 11 <!-- 周围漂浮的小圆圈 -->
12 <view 12 <view
13 - v-for="(item, index) in floatingItems" 13 + v-for="(item) in floatingItems"
14 :key="item.id" 14 :key="item.id"
15 class="floating-item" 15 class="floating-item"
16 - :class="{ 'collecting': item.collecting, 'stacked': item.stacked }" 16 + :style="getItemStyle(item)"
17 - :style="getItemStyle(item, index)" 17 + @tap="collectItem(item)"
18 - @tap="collectItem(item, index)"
19 > 18 >
20 - <view class="item-content"> 19 + <view v-if="item.type === 'steps'" class="item-content">
21 - <text class="item-value">{{ item.value }}</text> 20 + <text class="item-value">{{ item.steps }}步</text>
22 - <text class="item-type">{{ item.type === 'steps' ? '步' : '分' }}</text> 21 + <text class="item-type">{{ item.value }}分</text>
23 </view> 22 </view>
24 - <!-- 堆叠数量显示 --> 23 + <view v-else class="item-content">
25 - <view v-if="item.stackCount > 1" class="stack-count"> 24 + <text class="item-value">奖励</text>
26 - <text>{{ item.stackCount }}</text> 25 + <text class="item-type">{{ item.value }}分</text>
27 </view> 26 </view>
28 </view> 27 </view>
29 28
30 <!-- 一键收取按钮 --> 29 <!-- 一键收取按钮 -->
31 - <view 30 + <!-- <view
32 - v-if="floatingItems.length > 3" 31 + v-if="floatingItems.length > 0"
33 class="collect-all-btn" 32 class="collect-all-btn"
34 @tap="collectAll" 33 @tap="collectAll"
35 > 34 >
36 <text>一键收取</text> 35 <text>一键收取</text>
37 - </view> 36 + </view> -->
38 -
39 - <!-- 收集特效 -->
40 - <view
41 - v-for="effect in collectEffects"
42 - :key="effect.id"
43 - class="collect-effect"
44 - :style="effect.style"
45 - >
46 - <text>+{{ effect.value }}</text>
47 - </view>
48 </view> 37 </view>
49 </template> 38 </template>
50 39
51 <script setup> 40 <script setup>
52 -import { ref, computed, onMounted, nextTick } from 'vue' 41 +import { ref, onMounted, nextTick, defineProps, defineExpose } from 'vue'
53 import Taro from '@tarojs/taro' 42 import Taro from '@tarojs/taro'
54 43
44 +// 定义props
45 +const props = defineProps({
46 + height: {
47 + type: String,
48 + default: '30vh'
49 + }
50 +})
51 +
55 // 响应式数据 52 // 响应式数据
56 -const totalPoints = ref(1250) // 总积分 53 +const totalPoints = ref(12500) // 总积分
57 -const animatedTotalPoints = ref(1250) // 动画中的总积分 54 +const animatedTotalPoints = ref(12500) // 动画中的总积分
58 const floatingItems = ref([]) // 漂浮的积分项 55 const floatingItems = ref([]) // 漂浮的积分项
59 -const collectEffects = ref([]) // 收集特效数组 56 +const isCollecting = ref(false) // 是否正在收集,防止重复触发
60 -const isCollecting = ref(false) // 是否正在收集
61 57
62 /** 58 /**
63 - * 生成模拟数据 59 + * 生成模拟数据并分配随机位置
64 */ 60 */
65 const generateMockData = () => { 61 const generateMockData = () => {
66 const mockItems = [ 62 const mockItems = [
67 - { id: 1, type: 'steps', value: 500, collected: false }, 63 + { id: 1, type: 'steps', value: 5000, steps: 5000 },
68 - { id: 2, type: 'points', value: 50, collected: false }, 64 + { id: 2, type: 'points', value: 500 },
69 - { id: 3, type: 'steps', value: 800, collected: false }, 65 + { id: 3, type: 'steps', value: 8000, steps: 5000 },
70 - { id: 4, type: 'points', value: 30, collected: false }, 66 + { id: 4, type: 'points', value: 30 },
71 - { id: 5, type: 'steps', value: 1200, collected: false }, 67 + { id: 5, type: 'steps', value: 12000, steps: 12000 },
72 - { id: 6, type: 'points', value: 80, collected: false }, 68 + { id: 6, type: 'points', value: 800 },
73 - { id: 7, type: 'points', value: 25, collected: false }, 69 + { id: 7, type: 'points', value: 250 },
74 - { id: 8, type: 'steps', value: 600, collected: false }, 70 + { id: 8, type: 'steps', value: 6000, steps: 6000 },
75 - { id: 9, type: 'points', value: 100, collected: false }, 71 + { id: 9, type: 'points', value: 1000 },
76 - { id: 10, type: 'steps', value: 1000, collected: false }, 72 + { id: 10, type: 'steps', value: 10000, steps: 10000 },
77 - { id: 11, type: 'points', value: 100, collected: false }, 73 + ].map(item => ({ ...item, collecting: false })); // 初始化collecting状态
78 - { id: 12, type: 'steps', value: 1000, collected: false }, 74 +
79 - { id: 13, type: 'points', value: 100, collected: false }, 75 + const maxValue = Math.max(...mockItems.map(i => i.value));
80 - { id: 14, type: 'steps', value: 1000, collected: false }, 76 + const baseSize = 80;
81 - { id: 15, type: 'points', value: 100, collected: false }, 77 + const { windowWidth, windowHeight } = Taro.getWindowInfo();
82 - { id: 16, type: 'steps', value: 1000, collected: false }, 78 + const positionedItems = [];
83 - { id: 17, type: 'points', value: 100, collected: false }, 79 +
84 - { id: 18, type: 'steps', value: 1000, collected: false }, 80 + // 为每个项目分配一个不重叠的随机位置
85 - { id: 19, type: 'points', value: 100, collected: false }, 81 + return mockItems.map(item => {
86 - { id: 20, type: 'steps', value: 1000, collected: false }, 82 + let x, y, hasCollision;
87 - ] 83 + const maxAttempts = 100; // 限制尝试次数以避免无限循环
88 - 84 + let attempts = 0;
89 - // 处理堆叠逻辑 85 + const centerNoFlyZone = 25; // 中心圆形25%的禁飞区半径
90 - const processedItems = [] 86 +
91 - const itemGroups = {} 87 + // 计算项目大小和半径
92 - 88 + const sizeRatio = item.value / maxValue;
93 - mockItems.forEach(item => { 89 + const size = baseSize + (sizeRatio * 40); // rpx
94 - const key = `${item.type}_${item.value}` 90 + const radiusXPercent = (size / 750) * 100 / 2 * (windowWidth / windowHeight) ; // 归一化为高度的百分比
95 - if (itemGroups[key]) { 91 +
96 - itemGroups[key].stackCount++ 92 + // 定义安全区域
97 - } else { 93 + const minX = radiusXPercent;
98 - itemGroups[key] = { ...item, stackCount: 1, stacked: false } 94 + const maxX = 100 - radiusXPercent;
99 - processedItems.push(itemGroups[key]) 95 + const minY = radiusXPercent + 5;
96 + const maxY = 100 - radiusXPercent - 15;
97 +
98 + do {
99 + attempts++;
100 + if (attempts > maxAttempts) {
101 + console.warn('无法为项目找到不重叠的位置:', item);
102 + break; // 超过尝试次数,接受当前位置
103 + }
104 +
105 + // 在计算出的边界内生成位置
106 + x = Math.random() * (maxX - minX) + minX;
107 + y = Math.random() * (maxY - minY) + minY;
108 +
109 + // 检查与中心禁飞区的距离
110 + const dxCenter = x - 50;
111 + const dyCenter = y - 50;
112 + const distanceFromCenter = Math.sqrt(dxCenter * dxCenter + dyCenter * dyCenter);
113 + if (distanceFromCenter < centerNoFlyZone) {
114 + hasCollision = true;
115 + continue;
100 } 116 }
101 - })
102 117
103 - // 标记堆叠项 118 + // 检查与其他项目的碰撞
104 - processedItems.forEach(item => { 119 + hasCollision = false;
105 - if (item.stackCount > 1) { 120 + for (const pItem of positionedItems) {
106 - item.stacked = true 121 + const dx = x - pItem.x;
122 + const dy = y - pItem.y;
123 + const distance = Math.sqrt(dx * dx + dy * dy);
124 + const combinedRadius = radiusXPercent + pItem.radiusXPercent;
125 +
126 + if (distance < combinedRadius) {
127 + hasCollision = true;
128 + break;
129 + }
107 } 130 }
108 - }) 131 + } while (hasCollision);
109 132
110 - return processedItems 133 + positionedItems.push({ ...item, x, y, radiusXPercent });
134 + return { ...item, x, y };
135 + });
111 } 136 }
112 137
113 /** 138 /**
114 - * 获取项目样式(位置和大小 139 + * 获取项目样式(位置、大小和动画
115 */ 140 */
116 -const getItemStyle = (item, index) => { 141 +const getItemStyle = (item) => {
117 - const centerX = 375 // 屏幕中心X 142 + const baseSize = 80;
118 - const centerY = 400 // 屏幕中心Y 143 + const maxValue = Math.max(...(floatingItems.value.map(i => i.value).length > 0 ? floatingItems.value.map(i => i.value) : [1]));
119 - const radius = 200 // 分布半径 144 + const sizeRatio = item.value / maxValue;
120 - 145 + const size = baseSize + (sizeRatio * 40);
121 - // 根据索引计算角度 146 +
122 - const angle = (index * 45) + (Math.random() * 30 - 15) // 添加随机偏移 147 + const style = {
123 - const radian = (angle * Math.PI) / 180
124 -
125 - // 计算位置
126 - const x = centerX + Math.cos(radian) * (radius + Math.random() * 50)
127 - const y = centerY + Math.sin(radian) * (radius + Math.random() * 50)
128 -
129 - // 根据数值大小计算圆圈大小
130 - const baseSize = 80
131 - const maxValue = Math.max(...floatingItems.value.map(i => i.value))
132 - const sizeRatio = item.value / maxValue
133 - const size = baseSize + (sizeRatio * 40)
134 -
135 - return {
136 position: 'absolute', 148 position: 'absolute',
137 - left: `${x - size/2}rpx`, 149 + left: `${item.x}%`,
138 - top: `${y - size/2}rpx`, 150 + top: `${item.y}%`,
139 width: `${size}rpx`, 151 width: `${size}rpx`,
140 height: `${size}rpx`, 152 height: `${size}rpx`,
141 - transform: item.collecting ? 'scale(0)' : 'scale(1)', 153 + transform: 'translate(-50%, -50%) scale(1)',
142 - transition: 'all 0.5s ease-in-out' 154 + transition: 'all 0.8s cubic-bezier(0.5, -0.5, 0.5, 1.5)',
155 + zIndex: 15,
156 + };
157 +
158 + if (item.collecting) {
159 + style.left = '50%';
160 + style.top = '50%';
161 + style.transform = 'translate(-50%, -50%) scale(0)';
162 + style.opacity = 0;
163 + style.zIndex = 20; // 飞向中心时置于顶层
143 } 164 }
165 +
166 + return style;
144 } 167 }
145 168
146 /** 169 /**
147 * 收集单个项目 170 * 收集单个项目
148 */ 171 */
149 -const collectItem = async (item, index) => { 172 +const collectItem = (item) => {
150 - if (item.collecting || isCollecting.value) return 173 + if (item.collecting) return;
151 - 174 + item.collecting = true;
152 - item.collecting = true
153 -
154 - // 创建收集特效
155 - const effect = {
156 - id: Date.now(),
157 - value: item.type === 'steps' ? Math.floor(item.value / 10) : item.value,
158 - style: {
159 - position: 'absolute',
160 - left: '50%',
161 - top: '50%',
162 - transform: 'translate(-50%, -50%)',
163 - opacity: 1,
164 - transition: 'all 1s ease-out'
165 - }
166 - }
167 -
168 - collectEffects.value.push(effect)
169 175
170 - // 动画效果
171 - await nextTick()
172 - effect.style.transform = 'translate(-50%, -150%)'
173 - effect.style.opacity = 0
174 -
175 - // 更新总积分(步数转换为积分,比例1:10)
176 - const pointsToAdd = item.type === 'steps' ? Math.floor(item.value / 10) : item.value
177 - const stackMultiplier = item.stackCount || 1
178 - const totalToAdd = pointsToAdd * stackMultiplier
179 -
180 - // 数字滚动效果
181 - animateNumber(totalPoints.value, totalPoints.value + totalToAdd)
182 - totalPoints.value += totalToAdd
183 -
184 - // 延迟移除项目和特效
185 setTimeout(() => { 176 setTimeout(() => {
186 - floatingItems.value.splice(index, 1) 177 + const totalToAdd = item.type === 'steps' ? Math.floor(item.value / 10) : item.value;
187 - collectEffects.value = collectEffects.value.filter(e => e.id !== effect.id) 178 + animateNumber(totalPoints.value, totalPoints.value + totalToAdd);
188 - }, 1000) 179 + totalPoints.value += totalToAdd;
180 +
181 + floatingItems.value = floatingItems.value.filter(i => i.id !== item.id);
182 + }, 800); // 动画时长
189 } 183 }
190 184
191 /** 185 /**
192 * 一键收取所有积分 186 * 一键收取所有积分
193 */ 187 */
194 const collectAll = async () => { 188 const collectAll = async () => {
195 - if (isCollecting.value) return 189 + if (isCollecting.value) return;
196 - 190 + isCollecting.value = true;
197 - isCollecting.value = true
198 191
199 - // 计算总积分 192 + let totalToAdd = 0;
200 - let totalToAdd = 0 193 + const itemsToCollect = [...floatingItems.value];
201 - floatingItems.value.forEach(item => {
202 - const pointsToAdd = item.type === 'steps' ? Math.floor(item.value / 10) : item.value
203 - const stackMultiplier = item.stackCount || 1
204 - totalToAdd += pointsToAdd * stackMultiplier
205 - })
206 194
207 - // 批量收集动画 195 + itemsToCollect.forEach((item, index) => {
208 - floatingItems.value.forEach((item, index) => {
209 setTimeout(() => { 196 setTimeout(() => {
210 - item.collecting = true 197 + item.collecting = true;
211 - }, index * 100) 198 + }, index * 80); // 依次触发动画
212 - }) 199 + totalToAdd += item.value;
213 - 200 + });
214 - // 创建总收集特效
215 - const effect = {
216 - id: Date.now(),
217 - value: totalToAdd,
218 - style: {
219 - position: 'absolute',
220 - left: '50%',
221 - top: '50%',
222 - transform: 'translate(-50%, -50%)',
223 - opacity: 1,
224 - fontSize: '48rpx',
225 - color: '#ff6b35',
226 - fontWeight: 'bold',
227 - transition: 'all 1.5s ease-out'
228 - }
229 - }
230 -
231 - collectEffects.value.push(effect)
232 -
233 - await nextTick()
234 - effect.style.transform = 'translate(-50%, -200%)'
235 - effect.style.opacity = 0
236 201
237 - // 数字滚动效果 202 + const totalAnimationTime = itemsToCollect.length * 80 + 800;
238 - animateNumber(totalPoints.value, totalPoints.value + totalToAdd)
239 - totalPoints.value += totalToAdd
240 -
241 - // 清空所有项目
242 setTimeout(() => { 203 setTimeout(() => {
243 - floatingItems.value = [] 204 + animateNumber(totalPoints.value, totalPoints.value + totalToAdd);
244 - collectEffects.value = [] 205 + totalPoints.value += totalToAdd;
245 - isCollecting.value = false
246 206
247 - // 重新生成数据(模拟新的积分) 207 + floatingItems.value = [];
248 - setTimeout(() => { 208 + isCollecting.value = false;
249 - floatingItems.value = generateMockData() 209 +
250 - }, 2000) 210 + // 模拟2秒后重新生成
251 - }, 1500) 211 + // setTimeout(() => {
212 + // floatingItems.value = generateMockData();
213 + // }, 2000);
214 + }, totalAnimationTime);
252 } 215 }
253 216
254 /** 217 /**
255 * 数字滚动动画 218 * 数字滚动动画
256 */ 219 */
257 const animateNumber = (start, end) => { 220 const animateNumber = (start, end) => {
258 - const duration = 1000 221 + const duration = 800;
259 - const startTime = Date.now() 222 + const startTime = Date.now();
260 - const difference = end - start 223 + const difference = end - start;
261 224
262 const animate = () => { 225 const animate = () => {
263 - const elapsed = Date.now() - startTime 226 + const elapsed = Date.now() - startTime;
264 - const progress = Math.min(elapsed / duration, 1) 227 + const progress = Math.min(elapsed / duration, 1);
265 - 228 + const easeOut = 1 - Math.pow(1 - progress, 3);
266 - // 使用缓动函数 229 + animatedTotalPoints.value = Math.floor(start + difference * easeOut);
267 - const easeOut = 1 - Math.pow(1 - progress, 3)
268 - animatedTotalPoints.value = Math.floor(start + difference * easeOut)
269 230
270 if (progress < 1) { 231 if (progress < 1) {
271 - requestAnimationFrame(animate) 232 + requestAnimationFrame(animate);
272 - }
273 } 233 }
274 - 234 + };
275 - animate() 235 + animate();
276 } 236 }
277 237
238 +// 暴露方法给父组件
239 +defineExpose({
240 + collectAll
241 +})
242 +
278 // 组件挂载时初始化数据 243 // 组件挂载时初始化数据
279 onMounted(() => { 244 onMounted(() => {
280 - floatingItems.value = generateMockData() 245 + floatingItems.value = generateMockData();
281 }) 246 })
282 </script> 247 </script>
283 248
...@@ -286,7 +251,7 @@ onMounted(() => { ...@@ -286,7 +251,7 @@ onMounted(() => {
286 position: relative; 251 position: relative;
287 width: 100vw; 252 width: 100vw;
288 height: 100vh; 253 height: 100vh;
289 - background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); 254 + // background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
290 overflow: hidden; 255 overflow: hidden;
291 } 256 }
292 257
...@@ -297,12 +262,12 @@ onMounted(() => { ...@@ -297,12 +262,12 @@ onMounted(() => {
297 transform: translate(-50%, -50%); 262 transform: translate(-50%, -50%);
298 width: 200rpx; 263 width: 200rpx;
299 height: 200rpx; 264 height: 200rpx;
300 - background: linear-gradient(135deg, #ff6b35, #f7931e); 265 + background: linear-gradient(135deg, #4A90E2, #4d96ea);
301 border-radius: 50%; 266 border-radius: 50%;
302 display: flex; 267 display: flex;
303 align-items: center; 268 align-items: center;
304 justify-content: center; 269 justify-content: center;
305 - box-shadow: 0 8rpx 32rpx rgba(255, 107, 53, 0.3); 270 + box-shadow: 0 8rpx 32rpx rgba(53, 144, 255, 0.3);
306 z-index: 10; 271 z-index: 10;
307 } 272 }
308 273
...@@ -322,12 +287,12 @@ onMounted(() => { ...@@ -322,12 +287,12 @@ onMounted(() => {
322 display: block; 287 display: block;
323 font-size: 24rpx; 288 font-size: 24rpx;
324 margin-top: 8rpx; 289 margin-top: 8rpx;
325 - opacity: 0.9; 290 + // opacity: 0.9;
326 } 291 }
327 292
328 .floating-item { 293 .floating-item {
329 position: absolute; 294 position: absolute;
330 - background: rgba(255, 255, 255, 0.9); 295 + background: rgb(62, 144, 239);
331 border-radius: 50%; 296 border-radius: 50%;
332 display: flex; 297 display: flex;
333 align-items: center; 298 align-items: center;
...@@ -335,33 +300,25 @@ onMounted(() => { ...@@ -335,33 +300,25 @@ onMounted(() => {
335 box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.1); 300 box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.1);
336 cursor: pointer; 301 cursor: pointer;
337 animation: float 3s ease-in-out infinite; 302 animation: float 3s ease-in-out infinite;
338 -
339 - &.stacked {
340 - border: 4rpx solid #ff6b35;
341 - }
342 -
343 - &.collecting {
344 - transform: scale(0) !important;
345 - }
346 } 303 }
347 304
348 .item-content { 305 .item-content {
349 text-align: center; 306 text-align: center;
350 - color: #333; 307 + color: #FFF;
351 } 308 }
352 309
353 .item-value { 310 .item-value {
354 display: block; 311 display: block;
355 - font-size: 28rpx; 312 + font-size: 22rpx;
356 - font-weight: bold;
357 line-height: 1; 313 line-height: 1;
358 } 314 }
359 315
360 .item-type { 316 .item-type {
361 display: block; 317 display: block;
362 - font-size: 20rpx; 318 + font-size: 23rpx;
363 margin-top: 4rpx; 319 margin-top: 4rpx;
364 - opacity: 0.7; 320 + font-weight: bold;
321 + // opacity: 0.7;
365 } 322 }
366 323
367 .stack-count { 324 .stack-count {
...@@ -395,26 +352,18 @@ onMounted(() => { ...@@ -395,26 +352,18 @@ onMounted(() => {
395 z-index: 20; 352 z-index: 20;
396 } 353 }
397 354
398 -.collect-effect {
399 - pointer-events: none;
400 - color: #ff6b35;
401 - font-size: 36rpx;
402 - font-weight: bold;
403 - z-index: 30;
404 -}
405 -
406 @keyframes float { 355 @keyframes float {
407 0%, 100% { 356 0%, 100% {
408 - transform: translateY(0px) rotate(0deg); 357 + transform: translate(-50%, -50%) translateY(0px) rotate(0deg);
409 } 358 }
410 25% { 359 25% {
411 - transform: translateY(-10px) rotate(1deg); 360 + transform: translate(-50%, -50%) translateY(-10px) rotate(1deg);
412 } 361 }
413 50% { 362 50% {
414 - transform: translateY(-5px) rotate(-1deg); 363 + transform: translate(-50%, -50%) translateY(-5px) rotate(-1deg);
415 } 364 }
416 75% { 365 75% {
417 - transform: translateY(-15px) rotate(0.5deg); 366 + transform: translate(-50%, -50%) translateY(-15px) rotate(0.5deg);
418 } 367 }
419 } 368 }
420 369
...@@ -430,7 +379,7 @@ onMounted(() => { ...@@ -430,7 +379,7 @@ onMounted(() => {
430 } 379 }
431 380
432 .points-label { 381 .points-label {
433 - font-size: 20rpx; 382 + font-size: 24rpx;
434 } 383 }
435 } 384 }
436 </style> 385 </style>
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
2 * index页面样式 2 * index页面样式
3 */ 3 */
4 .index { 4 .index {
5 - padding: 20px; 5 + // padding: 20px;
6 6
7 .nut-button { 7 .nut-button {
8 margin-bottom: 20px; 8 margin-bottom: 20px;
......
1 <!-- 1 <!--
2 * @Date: 2025-06-28 10:33:00 2 * @Date: 2025-06-28 10:33:00
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2025-08-27 15:22:35 4 + * @LastEditTime: 2025-08-27 17:13:11
5 * @FilePath: /lls_program/src/pages/index/index.vue 5 * @FilePath: /lls_program/src/pages/index/index.vue
6 * @Description: 文件描述 6 * @Description: 文件描述
7 --> 7 -->
8 <template> 8 <template>
9 <view class="index"> 9 <view class="index">
10 - <nut-button type="primary" @click="onClick">按钮</nut-button> 10 + <PointsCollector ref="pointsCollectorRef" height="30vh" />
11 - <nut-button type="success" @click="showPointsCollector" style="margin-left: 20rpx;">积分收集</nut-button> 11 + <nut-button type="success" @click="handleCollectAll" style="margin-top: 20rpx;">一键收取</nut-button>
12 - <nut-toast v-model:visible="show" msg="你成功了" />
13 - <!-- <View className="text-[#acc855] text-[100px]">Hello world!</View> -->
14 -
15 - <!-- 积分收集组件 -->
16 - <PointsCollector v-if="showCollector" />
17 </view> 12 </view>
18 </template> 13 </template>
19 14
...@@ -25,18 +20,15 @@ import { useDidShow, useReady } from '@tarojs/taro' ...@@ -25,18 +20,15 @@ import { useDidShow, useReady } from '@tarojs/taro'
25 import PointsCollector from '@/components/PointsCollector.vue' 20 import PointsCollector from '@/components/PointsCollector.vue'
26 import "./index.less"; 21 import "./index.less";
27 22
28 -const show = ref(false) 23 +const pointsCollectorRef = ref(null)
29 -const showCollector = ref(false)
30 -
31 -const onClick = () => {
32 - show.value = true
33 -}
34 24
35 /** 25 /**
36 - * 显示积分收集组件 26 + * 触发积分收集组件的一键收取
37 */ 27 */
38 -const showPointsCollector = () => { 28 +const handleCollectAll = () => {
39 - showCollector.value = !showCollector.value 29 + if (pointsCollectorRef.value) {
30 + pointsCollectorRef.value.collectAll()
31 + }
40 } 32 }
41 33
42 // 生命周期钩子 34 // 生命周期钩子
......