feat: add dynamic nav, fix album preview and store types

add dynamic TopNavBar to goods page that updates styling based on scroll position
fix album page preview logic, replace uni preview with vant showImagePreview and correct typos
add TypeScript type annotation to picture store action
clean up album page layout and fix invalid img tag
use computed album list from picture store
This commit is contained in:
duanshuwen
2026-05-31 22:06:11 +08:00
parent 6c353163df
commit e3f8e94547
3 changed files with 25 additions and 24 deletions

View File

@@ -1,45 +1,40 @@
<template> <template>
<div class="bg-[#f5f7fa] flex flex-col h-screen overflow-hidden"> <div class="bg-[#f5f7fa] flex flex-col h-screen overflow-hidden">
<TopNavBar title="房间相册" backgroundColor="transparent" /> <TopNavBar class="shrink-0" :title="`房间相册(${albumList.length})`" backgroundColor="transparent" />
<div class="p-8">
<span class="ml-[4px] text-[18px] text-[#171717] font-medium">全部({{ albumList.length }})</span>
</div>
<scroll-div scroll-y class="scroll-container overflow-auto"> <div
<div class="pl-4 pr-4 pb-24"> class="scroll-container min-h-0 flex-1 overflow-auto scrollbar-none [-ms-overflow-style:none] [&::-webkit-scrollbar]:hidden">
<div class="pb-[24px]">
<div class="grid-container"> <div class="grid-container">
<div class="album-item" v-for="(item, index) in albumList" :key="index"> <div class="album-item" v-for="(item, index) in albumList" :key="index">
<div class="album-image-wrapper"> <div class="album-image-wrapper">
<img class="album-image" :src="item.photoUrl" mode="aspectFill" @click="handlePrediv(item.photoUrl)"> <img class="album-image" :src="item.photoUrl" @click="handlePreview(item.photoUrl)">
</image>
<div class="album-title">{{ item.name }}</div> <div class="album-title">{{ item.name }}</div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</scroll-div> </div>
</div> </div>
</template> </template>
<script setup> <script setup>
import { ref } from "vue"; import { computed } from "vue";
import TopNavBar from "@/components/TopNavBar/index.vue";
import { usePictureStore } from "@/store"; import { usePictureStore } from "@/store";
import { showImagePreview } from 'vant';
import TopNavBar from "@/components/TopNavBar/index.vue";
const pictureStore = usePictureStore(); const pictureStore = usePictureStore();
const albumList = ref([]); const albumList = computed(() =>
Array.isArray(pictureStore.previewImageData) ? pictureStore.previewImageData : [],
// TODO );
// onLoad(() => {
// albumList.value = pictureStore.predivImageData;
// pictureStore.setPredivImageData([]);
// });
// 处理图片预览 // 处理图片预览
const handlePrediv = (photoUrl) => { const handlePreview = (photoUrl) => {
uni.predivImage({ showImagePreview({
current: photoUrl, images: albumList.value.map((item) => item.photoUrl)
urls: albumList.value.map((item) => item.photoUrl),
}); });
}; };
</script> </script>

View File

@@ -1,5 +1,8 @@
<template> <template>
<div class="flex flex-col h-screen bg-white"> <div class="flex flex-col h-screen bg-white">
<TopNavBar fixed :title="navOpacity < 0.5 ? '' : '商品详情'" :background="`rgba(255, 255, 255, ${navOpacity})`"
:titleColor="navOpacity < 0.5 ? '#ffffff' : '#000000'"
:backIconColor="navOpacity < 0.5 ? '#ffffff' : '#000000'" />
<!-- 滚动区域 --> <!-- 滚动区域 -->
<div class="flex-1 overflow-y-auto scrollbar-none [-ms-overflow-style:none] [&::-webkit-scrollbar]:hidden" <div class="flex-1 overflow-y-auto scrollbar-none [-ms-overflow-style:none] [&::-webkit-scrollbar]:hidden"
@scroll="handleScroll"> @scroll="handleScroll">
@@ -63,6 +66,7 @@ import { onMounted, ref } from "vue";
import { useRoute, useRouter } from 'vue-router' import { useRoute, useRouter } from 'vue-router'
import { goodsDetail, commodityDailyPriceList } from "@/api/goods"; import { goodsDetail, commodityDailyPriceList } from "@/api/goods";
import { DateUtils } from "@/utils/dateUtils"; import { DateUtils } from "@/utils/dateUtils";
import TopNavBar from "@/components/TopNavBar/index.vue";
import ImageSwiper from "@/components/ImageSwiper/index.vue"; import ImageSwiper from "@/components/ImageSwiper/index.vue";
import GoodInfo from "./components/GoodInfo/index.vue"; import GoodInfo from "./components/GoodInfo/index.vue";
import Calender from "@/components/Calender/index.vue"; import Calender from "@/components/Calender/index.vue";
@@ -77,14 +81,16 @@ const router = useRouter()
const route = useRoute() const route = useRoute()
// 导航栏透明度 - 默认透明,随滚动变为不透明 // 导航栏透明度 - 默认透明,随滚动变为不透明
const navOpacity = ref(0);
const calendarVisible = ref(false); const calendarVisible = ref(false);
const goodsData = ref({}); const goodsData = ref({});
// 处理滚动事件 // 处理滚动事件
const handleScroll = (e) => { const handleScroll = (e) => {
const scrollTop = e.detail.scrollTop; const scrollTop = Number(e?.target?.scrollTop ?? e?.currentTarget?.scrollTop ?? e?.detail?.scrollTop ?? 0);
// 设置一个阈值当滚动超过200px时导航栏完全不透明 // 设置一个阈值当滚动超过200px时导航栏完全不透明
const threshold = 200; const threshold = 200;
navOpacity.value = Math.min(scrollTop / threshold, 1);
}; };
const selectedDate = ref({ const selectedDate = ref({

View File

@@ -8,7 +8,7 @@ export const usePictureStore = defineStore("picture", {
}, },
actions: { actions: {
setPreviewImageData(data) { setPreviewImageData(data: any[]) {
this.previewImageData = data; this.previewImageData = data;
}, },
}, },