This commit is contained in:
18631081161 2025-07-25 14:13:08 +08:00
parent 7487e02a4d
commit dc7c7cc475
2 changed files with 227 additions and 215 deletions

View File

@ -1,110 +1,116 @@
<template>
<view class="goods-item" @click="onItemClick">
<view class="goods-image">
<image v-if="goodsItem.imgUrl" :src="goodsItem.imgUrl" class="image" mode="aspectFill" />
</view>
<view class="goods-item" @click="onItemClick">
<view class="goods-image">
<image v-if="goodsItem.imgUrl" :src="goodsItem.imgUrl" class="image" mode="aspectFill" />
</view>
<text class="goods-title myZt-500w">{{ goodsItem.title }}</text>
<text class="goods-title myZt-500w">{{ goodsItem.title }}</text>
<text class="goods-status myZt-300w">现货发售中</text>
<text class="goods-status myZt-300w">现货发售中</text>
<view class="goods-price">
<text class="price-value myZt-500w">{{ goodsItem.price }}</text>
<text class="price-unit myZt-500w">/ </text>
</view>
</view>
<view class="goods-price">
<text class="price-value myZt-500w">{{ goodsItem.price }}</text>
<text class="price-unit myZt-500w">/ </text>
</view>
</view>
</template>
<script setup>
/**
* 商品项组件
*/
import { defineProps, defineEmits } from 'vue';
/**
* 商品项组件
*/
import {
defineProps,
defineEmits
} from 'vue';
//
const props = defineProps({
/**
* 商品信息
*/
goodsItem: {
type: Object,
required: true,
default: () => ({
id: '',
title: '',
imgUrl: '',
price: '0',
type: ''
})
}
});
//
const props = defineProps({
/**
* 商品信息
*/
goodsItem: {
type: Object,
required: true,
default: () => ({
id: '',
title: '',
imgUrl: '',
price: '0',
type: ''
})
}
});
//
const emit = defineEmits(['click']);
//
const emit = defineEmits(['click']);
/**
* 点击商品项
*/
const onItemClick = () => {
emit('click', props.goodsItem.id);
};
/**
* 点击商品项
*/
const onItemClick = () => {
emit('click', props.goodsItem.id);
};
</script>
<style lang="scss" scoped>
.goods-item {
height: 490.28rpx;
background-color: #FEF6D6;
border: 3rpx solid #F9D051;
border-radius: 40rpx;
display: flex;
flex-direction: column;
.goods-image {
width: 100%;
height: 320.83rpx;
background-color: #FFFFFF;
border-radius: 40rpx 40rpx 0 0;
overflow: hidden;
.image {
width: 100%;
height: 100%;
}
}
.goods-title {
width: 280.56rpx;
margin: 15.28rpx auto;
font-size: 25rpx;
color: #685952;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
text-overflow: ellipsis;
}
.goods-status {
font-size: 19.44rpx;
color: #FF6A6A;
margin-left: 24.31rpx;
}
.goods-price {
display: flex;
flex-direction: row;
margin-left: 20.31rpx;
.price-value {
font-size: 29.17rpx;
color: #87644E;
}
.price-unit {
font-size: 19.44rpx;
color: #87644E;
margin-top: 10rpx;
}
}
}
.goods-item {
height: 490.28rpx;
background-color: #FEF6D6;
border: 3rpx solid #F9D051;
border-radius: 40rpx;
display: flex;
flex-direction: column;
.goods-image {
width: 100%;
height: 320.83rpx;
background-color: #FFFFFF;
border-radius: 40rpx 40rpx 0 0;
overflow: hidden;
.image {
width: 100%;
height: 100%;
}
}
.goods-title {
width: 280.56rpx;
margin-top: 15.28rpx;
margin-left: 23.61rpx;
font-size: 25rpx;
color: #685952;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
text-overflow: ellipsis;
}
.goods-status {
font-size: 19.44rpx;
color: #FF6A6A;
margin-left: 24.31rpx;
margin-top: 15.97rpx;
}
.goods-price {
display: flex;
flex-direction: row;
margin-left: 20.31rpx;
margin-top: 18.75rpx;
.price-value {
font-size: 29.17rpx;
color: #87644E;
}
.price-unit {
font-size: 19.44rpx;
color: #87644E;
margin-top: 10rpx;
}
}
}
</style>

View File

@ -3,144 +3,150 @@
<view>
<z-paging ref="pagePaging" refresher-only @onRefresh="onRefresh" @scrolltolower="scrolltolower"
@scroll="scroll">
<view class="content">
<guyu-home-search style="width: 100%;"></guyu-home-search>
<!-- 公告 -->
<guyu-home-notice :notice-info="homeData?.noticeInfo" />
<!-- 轮播图 -->
<guyu-home-swiper :advert-list="homeData?.advertList" style="width: 100%;" />
<!-- 推荐位 -->
<guyu-home-recommend :rec-list="homeData?.recList" style="width: 100%;" />
<!-- 小程序中直接修改组件style为position: sticky;无效需要在组件外层套一层view -->
<view class="bar-view" style="z-index:97;position: sticky;top :0;background-color: #fff;">
<view :style="{ height: tabsBarHeight + 'px' }" class="status-bar"> </view>
<guyu-home-tabs ref="tabs" :list="homeData?.categories" @change="tabsChange" :current="current" />
<view class="bg"
style="display: flex; justify-content: center; width: 100%; background-image: url('@@:static/bg.png');">
<view class="content">
<guyu-home-search style="width: 100%;"></guyu-home-search>
<!-- 公告 -->
<guyu-home-notice :notice-info="homeData?.noticeInfo" />
<!-- 轮播图 -->
<guyu-home-swiper :advert-list="homeData?.advertList" style="width: 100%;" />
<!-- 推荐位 -->
<guyu-home-recommend :rec-list="homeData?.recList" style="width: 100%;" />
<!-- 小程序中直接修改组件style为position: sticky;无效需要在组件外层套一层view -->
<view class="bar-view" style="z-index:97;position: sticky;top :0;background-color: #fff;">
<view :style="{ height: tabsBarHeight + 'px' }" class="status-bar"> </view>
<guyu-home-tabs ref="tabs" :list="homeData?.categories" @change="tabsChange"
:current="current" />
</view>
<swiper class="swiper" :style="[{ height: swiperHeight + 'px' }]" :current="current"
@transition="swiperTransition" @animationfinish="swiperAnimationfinish">
<swiper-item class="swiper-item" v-for="(item, index) in homeData?.categories" :key="index">
<guyu-home-goods-list ref="swiperList" :tabIndex="index" :currentIndex="current"
@heightChanged="heightChanged">
</guyu-home-goods-list>
</swiper-item>
</swiper>
</view>
<swiper class="swiper" :style="[{ height: swiperHeight + 'px' }]" :current="current"
@transition="swiperTransition" @animationfinish="swiperAnimationfinish">
<swiper-item class="swiper-item" v-for="(item, index) in homeData?.categories" :key="index">
<guyu-home-goods-list ref="swiperList" :tabIndex="index" :currentIndex="current"
@heightChanged="heightChanged">
</guyu-home-goods-list>
</swiper-item>
</swiper>
</view>
</z-paging>
</view>
</template>
<script setup>
import { ref, onMounted } from 'vue';
import {
homeData,
isLoading,
error,
preloadHomeData,
refreshHomeData
} from '@/common/server/home';
//
const swiperHeight = ref(0);
const tabList = ref(['测试1', '测试2', '测试3', '测试4']);
const current = ref(0); // tabscurrenttab
const tabsBarHeight = ref(0);
const statusBarHeight = ref(uni.getSystemInfoSync().statusBarHeight);
const isQuerying = ref(false);
import {
ref,
onMounted
} from 'vue';
import {
homeData,
isLoading,
error,
preloadHomeData,
refreshHomeData
} from '@/common/server/home';
//
const swiperHeight = ref(0);
const tabList = ref(['测试1', '测试2', '测试3', '测试4']);
const current = ref(0); // tabscurrenttab
const tabsBarHeight = ref(0);
const statusBarHeight = ref(uni.getSystemInfoSync().statusBarHeight);
const isQuerying = ref(false);
//
const pagePaging = ref(null);
const tabs = ref(null);
const swiperList = ref(null);
//
const pagePaging = ref(null);
const tabs = ref(null);
const swiperList = ref(null);
onLoad(() => {
onLoad(() => {
});
//
onMounted(() => {
if (!homeData.value) preloadHomeData();
});
//
const scroll = (e) => {
// #ifdef MP
if (e.detail.scrollTop < 700 && statusBarHeight.value > 0) {
if (isQuerying.value) {
return;
}
isQuerying.value = true;
const query = uni.createSelectorQuery();
query.select('.bar-view').boundingClientRect(rect => {
if (rect) {
//
if (rect.top <= 0 && tabsBarHeight.value == 0) {
tabsBarHeight.value = statusBarHeight.value;
} else if (rect.top > 30 && statusBarHeight.value > 0) {
tabsBarHeight.value = 0;
}
}
isQuerying.value = false;
}).exec();
}
// #endif
};
// tabsswiper
const tabsChange = (index) => {
_setCurrent(index);
};
// reload
const onRefresh = () => {
swiperList.value[current.value].reload(() => {
//
pagePaging.value.endRefresh();
});
};
//
onMounted(() => {
if (!homeData.value) preloadHomeData();
});
//
const scroll = (e) => {
// #ifdef MP
if (e.detail.scrollTop < 700 && statusBarHeight.value > 0) {
if (isQuerying.value) {
return;
}
isQuerying.value = true;
const query = uni.createSelectorQuery();
query.select('.bar-view').boundingClientRect(rect => {
if (rect) {
//
if (rect.top <= 0 && tabsBarHeight.value == 0) {
tabsBarHeight.value = statusBarHeight.value;
} else if (rect.top > 30 && statusBarHeight.value > 0) {
tabsBarHeight.value = 0;
}
}
isQuerying.value = false;
}).exec();
}
// #endif
};
//
const scrolltolower = () => {
swiperList.value[current.value].doLoadMore();
};
// tabsswiper
const tabsChange = (index) => {
_setCurrent(index);
};
// swiper
const swiperTransition = (e) => {
tabs.value.setDx(e.detail.dx);
};
// reload
const onRefresh = () => {
swiperList.value[current.value].reload(() => {
//
pagePaging.value.endRefresh();
});
};
// swiper
const swiperAnimationfinish = (e) => {
_setCurrent(e.detail.current);
tabs.value.unlockDx();
};
//
const scrolltolower = () => {
swiperList.value[current.value].doLoadMore();
};
// swiper
const heightChanged = (height) => {
if (height === 0) {
// swiper-tabsView-slot="top"view
// uni.upx2px(80)slot="top"viewslot="top"view80rpx
height = uni.getSystemInfoSync().windowHeight - uni.upx2px(80);
}
swiperHeight.value = height;
};
// swiper
const swiperTransition = (e) => {
tabs.value.setDx(e.detail.dx);
};
const _setCurrent = (currentVal) => {
if (currentVal !== current.value) {
//tabtab
swiperList.value[current.value].clear();
}
current.value = currentVal;
};
// swiper
const swiperAnimationfinish = (e) => {
_setCurrent(e.detail.current);
tabs.value.unlockDx();
};
// swiper
const heightChanged = (height) => {
if (height === 0) {
// swiper-tabsView-slot="top"view
// uni.upx2px(80)slot="top"viewslot="top"view80rpx
height = uni.getSystemInfoSync().windowHeight - uni.upx2px(80);
}
swiperHeight.value = height;
};
const _setCurrent = (currentVal) => {
if (currentVal !== current.value) {
//tabtab
swiperList.value[current.value].clear();
}
current.value = currentVal;
};
</script>
<style lang="scss" scoped>
.content {
width: 96%;
margin-left: 2%;
background-color: url('@@:static/bg.png');
background-size: 100% 100%;
background-repeat: no-repeat;
}
.content {
width: 94%;
}
.swiper {
height: 1000px;
}
.swiper {
height: 1000px;
}
</style>