146 lines
4.2 KiB
Vue
146 lines
4.2 KiB
Vue
<!-- 滑动切换选项卡+吸顶演示(上一个tab数据不保留,滚动流畅) -->
|
||
<template>
|
||
<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>
|
||
<swiper class="swiper" :style="[{ height: swiperHeight + 'px' }]" :current="current"
|
||
@transition="swiperTransition" @animationfinish="swiperAnimationfinish">
|
||
<swiper-item class="swiper-item" v-for="(item, index) in tabList" :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); // tabs组件的current值,表示当前活动的tab选项
|
||
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);
|
||
|
||
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
|
||
};
|
||
|
||
// tabs通知swiper切换
|
||
const tabsChange = (index) => {
|
||
_setCurrent(index);
|
||
};
|
||
|
||
// 下拉刷新时,通知当前显示的列表进行reload操作
|
||
const onRefresh = () => {
|
||
swiperList.value[current.value].reload(() => {
|
||
//当当前显示的列表刷新结束,结束当前页面的刷新状态
|
||
pagePaging.value.endRefresh();
|
||
});
|
||
};
|
||
|
||
// 当滚动到底部时,通知当前显示的列表加载更多
|
||
const scrolltolower = () => {
|
||
swiperList.value[current.value].doLoadMore();
|
||
};
|
||
|
||
// swiper滑动中
|
||
const swiperTransition = (e) => {
|
||
tabs.value.setDx(e.detail.dx);
|
||
};
|
||
|
||
// 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"内view的高度,如果slot="top"内view的高度不为80rpx,则需要修改这个值
|
||
height = uni.getSystemInfoSync().windowHeight - uni.upx2px(80);
|
||
}
|
||
swiperHeight.value = height;
|
||
};
|
||
|
||
const _setCurrent = (currentVal) => {
|
||
if (currentVal !== current.value) {
|
||
//切换tab时,将上一个tab的数据清空
|
||
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;
|
||
}
|
||
|
||
.swiper {
|
||
height: 1000px;
|
||
}
|
||
</style> |