- 添加了 itemDetail 组件,用于展示商品详细信息 - 在 home 页面中集成了瀑布流列表组件 - 实现了商品列表的加载更多和下拉刷新功能 - 添加了商品详情弹窗组件
		
			
				
	
	
		
			158 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
			
		
		
	
	
			158 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
| <script setup>
 | ||
| import xPopup from '@/components/x-popup/index.vue'
 | ||
| import {goodStore} from "@/stores/goods/index.js";
 | ||
| import xImage from '@/components/x-image/index.vue'
 | ||
| import DetailPopup from '@/pages/home/components/DetailPopup/index.vue'
 | ||
| import {liveStore} from "~/stores/live/index.js";
 | ||
| import {ref} from "vue";
 | ||
| const {pageRef,itemList,getArtworkList,  loading: storeLoading,} = goodStore();
 | ||
| const {auctionData} = liveStore()
 | ||
| const showDetail=ref(false)
 | ||
| const localState = ref({
 | ||
|   finished: false,
 | ||
|   refreshing: false,
 | ||
|   showDetail: false,
 | ||
|   showHeight: ''
 | ||
| })
 | ||
| const onRefresh = async () => {
 | ||
|   try {
 | ||
|     localState.value.refreshing = true
 | ||
|     localState.value.finished = false
 | ||
|     const { finished } = await getArtworkList(true)
 | ||
|     localState.value.finished = finished
 | ||
|   } finally {
 | ||
|     localState.value.refreshing = false
 | ||
|   }
 | ||
| }
 | ||
| const props = defineProps({
 | ||
|   show: Boolean,
 | ||
|   title: {
 | ||
|     type: String,
 | ||
|     default: ''
 | ||
|   }
 | ||
| })
 | ||
| const scrollToCurrentItem = () => {
 | ||
|   if (!itemList.value?.length) return
 | ||
|   const currentIndex = itemList.value.findIndex(
 | ||
|       item => auctionData.value.artwork.index === item?.index
 | ||
|   )
 | ||
|   if (currentIndex > -1) {
 | ||
|     const container = document.querySelector('.list-container')
 | ||
|     const targetElement = document.querySelectorAll('.item-wrapper')[currentIndex]
 | ||
|     if (targetElement && container) {
 | ||
|       const containerTop = container.getBoundingClientRect().top
 | ||
|       const elementTop = targetElement.getBoundingClientRect().top
 | ||
|       const scrollTop = elementTop - containerTop + container.scrollTop
 | ||
|       container.scrollTo({
 | ||
|         top: scrollTop,
 | ||
|         behavior: 'smooth'
 | ||
|       })
 | ||
|     }
 | ||
|   }
 | ||
| }
 | ||
| const emit = defineEmits(['update:show'])
 | ||
| const showDetailInfo=ref(null)
 | ||
| const close = () => emit('update:show', false);
 | ||
| const openShow=(item)=>{
 | ||
|   showDetailInfo.value=item
 | ||
|   showDetail.value=true
 | ||
| 
 | ||
| }
 | ||
| const loadMore = async () => {
 | ||
|   pageRef.value.page++
 | ||
|   const { finished } = await getArtworkList()
 | ||
|   localState.value.finished = finished
 | ||
| }
 | ||
| watch(()=>{
 | ||
|   return auctionData.value?.artwork?.index
 | ||
| },(newValue)=>{
 | ||
|   })
 | ||
| watch(()=>props.show,async (newValue)=>{
 | ||
|   if (newValue){
 | ||
|     if(auctionData.value?.artwork?.index>itemList.value?.length+1){
 | ||
|       pageRef.value.pageSize=auctionData.value?.artwork?.index-itemList.value?.length
 | ||
|      await loadMore()
 | ||
|     }
 | ||
|  nextTick(()=>{
 | ||
|    scrollToCurrentItem()
 | ||
|  })
 | ||
|   }
 | ||
| })
 | ||
| </script>
 | ||
| 
 | ||
| <template>
 | ||
|   <div>
 | ||
|     <x-popup :show="show" @update:show="close">
 | ||
|       <template #title>
 | ||
|         <div class="text-#000 text-16px">{{ $t('home.tab1')}}</div>
 | ||
|         <div class="text-#939393 text-16px ml-14px">{{ $t('live_room.total') }}{{ pageRef.itemCount }}{{ $t('live_room.lots_num') }}</div>
 | ||
|       </template>
 | ||
|       <div>
 | ||
|         <van-pull-refresh
 | ||
|             v-model="localState.refreshing"
 | ||
|             :success-text="$t('home.refresh_show')"
 | ||
|             :success-duration="700"
 | ||
|             @refresh="onRefresh"
 | ||
|         >
 | ||
|           <template #success>
 | ||
|             <van-icon name="success" /> <span>{{ $t('home.refresh_show') }}</span>
 | ||
|           </template>
 | ||
|           <van-list
 | ||
|               v-model:loading="storeLoading"
 | ||
|               :finished="localState.finished"
 | ||
|               :finished-text="$t('home.finished_text')"
 | ||
|               @load="loadMore"
 | ||
| 
 | ||
|           >
 | ||
|             <div
 | ||
|                 v-for="(item,index) of itemList"
 | ||
|                 :key="item.uuid"
 | ||
|                 class="flex mb-21px item-wrapper"
 | ||
|                 @click="openShow(item)"
 | ||
|             >
 | ||
|               <div
 | ||
|                   class="mr-10px flex-shrink-0 rounded-4px overflow-hidden cursor-pointer relative"
 | ||
|               >
 | ||
|                 <xImage
 | ||
|                     :preview="false"
 | ||
|                     class="w-80px h-80px"
 | ||
|                     :src="item.artwork?.hdPic"
 | ||
|                     :alt="item?.artworkTitle"
 | ||
|                     loading="lazy"
 | ||
|                 />
 | ||
|                 <div class="w-45px h-17px bg-#2B53AC text-12px line-height-none flex justify-center items-center absolute top-2px left-2px text-#fff">LOT{{item.index}}</div>
 | ||
|                 <div  v-show="auctionData?.artwork?.index===item?.index" class="w-80px h-20px bg-#B58047 flex line-height-none justify-center items-center text-#fff text-12px bottom-0 absolute blink">{{ $t('live_room.cast') }}</div>
 | ||
|               </div>
 | ||
|               <div>
 | ||
|                 <div class="ellipsis line-height-20px text-16px font-600 min-h-40px">
 | ||
|                   {{ item.artworkTitle }}
 | ||
|                 </div>
 | ||
|                 <div class="text-14px text-#575757">{{ $t('home.start_price') }}:{{item?.startPriceCurrency}} {{item?.startPrice}}</div>
 | ||
|                 <div class="text-14px text-#B58047" v-if="item.soldPrice">{{ $t('home.close_price') }}:{{item.soldPrice}}</div>
 | ||
|               </div>
 | ||
|             </div>
 | ||
|           </van-list>
 | ||
|         </van-pull-refresh>
 | ||
|       </div>
 | ||
|     </x-popup>
 | ||
|     <DetailPopup v-model:show="showDetail" :detail-info="showDetailInfo"></DetailPopup>
 | ||
|   </div>
 | ||
| </template>
 | ||
| 
 | ||
| <style scoped>
 | ||
| .ellipsis {
 | ||
|   display: -webkit-box;
 | ||
|   -webkit-box-orient: vertical;
 | ||
|   -webkit-line-clamp: 2;
 | ||
|   overflow: hidden;
 | ||
|   text-overflow: ellipsis;
 | ||
| }
 | ||
| .blink {
 | ||
|   animation: fade 1s linear infinite;
 | ||
| }
 | ||
| 
 | ||
| @keyframes fade {
 | ||
|   0%, 100% { opacity: 1; }
 | ||
|   50% { opacity: 0.5; }
 | ||
| }
 | ||
| </style> |