hookehuyr

feat(相册): 添加弹窗打开关闭事件通知父组件

在FamilyAlbum组件中添加popup-open和popup-close事件,当上传弹窗打开或关闭时通知父组件Dashboard。父组件根据事件锁定或解锁页面滚动,防止弹窗打开时页面滚动。

在Dashboard组件中添加页面滚动锁定功能,通过计算属性和Taro API实现页面高度固定和滚动控制。
...@@ -129,6 +129,9 @@ import { Close, Photograph, IconFont } from '@nutui/icons-vue-taro'; ...@@ -129,6 +129,9 @@ import { Close, Photograph, IconFont } from '@nutui/icons-vue-taro';
129 import { getPhotoListAPI } from '@/api/photo'; 129 import { getPhotoListAPI } from '@/api/photo';
130 import UploadMediaPopup from '@/components/UploadMediaPopup.vue'; 130 import UploadMediaPopup from '@/components/UploadMediaPopup.vue';
131 131
132 +// 定义事件
133 +const emit = defineEmits(['popup-open', 'popup-close']);
134 +
132 // 视频播放相关状态 135 // 视频播放相关状态
133 const videoVisible = ref(false); 136 const videoVisible = ref(false);
134 const currentVideo = ref(null); 137 const currentVideo = ref(null);
...@@ -256,6 +259,8 @@ const openAlbumList = () => { ...@@ -256,6 +259,8 @@ const openAlbumList = () => {
256 */ 259 */
257 const navigateToUpload = () => { 260 const navigateToUpload = () => {
258 uploadPopupVisible.value = true; 261 uploadPopupVisible.value = true;
262 + // 通知父组件弹窗已打开
263 + emit('popup-open');
259 }; 264 };
260 265
261 /** 266 /**
...@@ -263,6 +268,8 @@ const navigateToUpload = () => { ...@@ -263,6 +268,8 @@ const navigateToUpload = () => {
263 */ 268 */
264 const closeUploadPopup = () => { 269 const closeUploadPopup = () => {
265 uploadPopupVisible.value = false; 270 uploadPopupVisible.value = false;
271 + // 通知父组件弹窗已关闭
272 + emit('popup-close');
266 }; 273 };
267 274
268 /** 275 /**
......
1 <!-- 1 <!--
2 * @Date: 2025-08-27 17:43:45 2 * @Date: 2025-08-27 17:43:45
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2025-09-22 10:31:20 4 + * @LastEditTime: 2025-09-23 11:08:57
5 * @FilePath: /lls_program/src/pages/Dashboard/index.vue 5 * @FilePath: /lls_program/src/pages/Dashboard/index.vue
6 * @Description: 首页 6 * @Description: 首页
7 --> 7 -->
8 <template> 8 <template>
9 - <view class="min-h-screen flex flex-col bg-white pb-16" style="background-color: #F9FAFB;"> 9 + <view class="min-h-screen flex flex-col bg-white pb-16" :style="pageStyle">
10 <!-- Hero section with family name and background image --> 10 <!-- Hero section with family name and background image -->
11 <view class=" bg-white rounded-xl shadow-md mx-4 mt-4 relative" :style="{ height: isTabletDevice ? '40vh' : '30vh' }"> 11 <view class=" bg-white rounded-xl shadow-md mx-4 mt-4 relative" :style="{ height: isTabletDevice ? '40vh' : '30vh' }">
12 <image :src="familyCover" mode="aspectFill" alt="Family background" class="w-full h-full object-cover rounded-xl" /> 12 <image :src="familyCover" mode="aspectFill" alt="Family background" class="w-full h-full object-cover rounded-xl" />
...@@ -152,7 +152,11 @@ ...@@ -152,7 +152,11 @@
152 <RankingCard ref="rankingCardRef" :onViewMore="openFamilyRank" /> 152 <RankingCard ref="rankingCardRef" :onViewMore="openFamilyRank" />
153 153
154 <!-- Family album --> 154 <!-- Family album -->
155 - <FamilyAlbum ref="familyAlbumRef" /> 155 + <FamilyAlbum
156 + ref="familyAlbumRef"
157 + @popup-open="lockPageScroll"
158 + @popup-close="unlockPageScroll"
159 + />
156 160
157 <BottomNav /> 161 <BottomNav />
158 162
...@@ -196,15 +200,64 @@ const finalTotalPoints = ref(0) ...@@ -196,15 +200,64 @@ const finalTotalPoints = ref(0)
196 const pendingPoints = ref([]) // 待收集的积分数据 200 const pendingPoints = ref([]) // 待收集的积分数据
197 const familyAlbumRef = ref(null) 201 const familyAlbumRef = ref(null)
198 202
203 +// 页面锁定相关状态
204 +const isPageLocked = ref(false)
205 +const pageHeight = ref(0)
206 +
199 const familyName = ref('') 207 const familyName = ref('')
200 const familySlogn = ref('') 208 const familySlogn = ref('')
201 const familyCover = ref('') 209 const familyCover = ref('')
202 const familyOwner = ref(false); 210 const familyOwner = ref(false);
203 211
204 // 广告遮罩层数据 212 // 广告遮罩层数据
205 -
206 const adOverlayRef = ref(null) 213 const adOverlayRef = ref(null)
207 214
215 +// 页面样式计算属性
216 +const pageStyle = computed(() => {
217 + const baseStyle = {
218 + 'background-color': '#F9FAFB'
219 + }
220 +
221 + if (isPageLocked.value && pageHeight.value > 0) {
222 + return {
223 + ...baseStyle,
224 + height: `${pageHeight.value}px`,
225 + overflow: 'hidden'
226 + }
227 + }
228 +
229 + return baseStyle
230 +})
231 +
232 +/**
233 + * 锁定页面滚动
234 + */
235 +const lockPageScroll = () => {
236 + // 获取当前视窗高度
237 + Taro.getSystemInfo({
238 + success: (res) => {
239 + pageHeight.value = res.windowHeight
240 + isPageLocked.value = true
241 + }
242 + })
243 +}
244 +
245 +/**
246 + * 解锁页面滚动
247 + */
248 +const unlockPageScroll = () => {
249 + isPageLocked.value = false
250 + pageHeight.value = 0
251 +
252 + // 解锁后滚动到页面底部
253 + setTimeout(() => {
254 + Taro.pageScrollTo({
255 + scrollTop: 99999, // 使用一个很大的数值确保滚动到底部
256 + duration: 50 // 滚动动画时长100ms
257 + })
258 + }, 50) // 延迟50ms确保页面解锁完成
259 +}
260 +
208 /** 261 /**
209 * 触发积分收集组件的一键收取 262 * 触发积分收集组件的一键收取
210 */ 263 */
......