图书馆小程序
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

225 lines
5.0 KiB

<template>
<view class="lending-container">
<!-- Tabs 吸顶 -->
<view class="tab-sticky">
<my-tabs
:tabData="tabData"
:defaultIndex="currentIndex"
:config="{ textColor: '#333' }"
@tabClick="tabClick"
/>
</view>
<!-- Swiper 内容区 -->
<swiper
class="swiper"
:current="currentIndex"
:style="{ height: currentSwiperHeight + 'px' }"
@animationfinish="onSwiperEnd"
@change="onSwiperChange"
duration="300"
>
<swiper-item class="swiper-item" v-for="(tabItem, tabIndex) in tabData" :key="tabIndex">
<view class="list-wrapper">
<!-- 加载中 -->
<uni-load-more status="loading" v-if="loadingMap[tabIndex]" />
<!-- 空数据 -->
<view class="empty" v-else-if="!listData[tabIndex] || listData[tabIndex].length === 0">
暂无借阅记录
</view>
<!-- 图书列表 -->
<block v-else>
<book-list-item
:class="'list-item-' + tabIndex"
v-for="(item, index) in listData[tabIndex]"
:key="index"
:data="item"
:ranking="index + 1"
@click="goToDetail(item)"
/>
</block>
</view>
</swiper-item>
</swiper>
</view>
</template>
<script>
import myTabs from "@/components/my-tabs/my-tabs.vue";
import bookListItem from "@/components/book-list-item/book-list-item.vue";
export default {
components: {
myTabs,
bookListItem
},
data() {
return {
tabData: [
{ label: "在借中" },
{ label: "将过期" },
{ label: "已过期" }
],
currentIndex: 0,
// 列表数据缓存
listData: {
0: [],
1: [],
2: []
},
// 每个页面的加载状态
loadingMap: {
0: true,
1: true,
2: true
},
// Swiper 高度自适应
currentSwiperHeight: 400,
swiperHeightData: {},
// 页面滚动
currentPageScrollTop: 0
};
},
onLoad() {
this.getListData(0);
},
onPageScroll(res) {
this.currentPageScrollTop = res.scrollTop;
},
methods: {
async getListData(index) {
this.loadingMap[index] = true;
setTimeout(() => {
const mockData = this.getMockListByStatus(index);
this.listData[index] = mockData;
this.loadingMap[index] = false;
this.$nextTick(() => {
this.calcSwiperHeight(index);
});
}, 600);
},
getMockListByStatus(status) {
const baseList = [
{
imgCover: "https://qiniu.aiyxlib.com/1606124577077",
title: "名侦探柯南",
nickname: "青山刚昌",
publish: "长春出版社",
isbn: "1001"
},
{
imgCover: "https://qiniu.aiyxlib.com/1606124577077",
title: "三体",
nickname: "刘慈欣",
publish: "重庆出版社",
isbn: "1002"
}
];
if (status === 0) return baseList;
if (status === 1) return [baseList[0]];
if (status === 2) return [];
return [];
},
calcSwiperHeight(index) {
const query = uni.createSelectorQuery().in(this);
query
.selectAll(`.list-item-${index}`)
.boundingClientRect((res) => {
let totalHeight = 0;
if (res && res.length) {
res.forEach((item) => {
totalHeight += item.height + 8;
});
} else {
totalHeight = 200;
}
this.swiperHeightData[index] = totalHeight;
this.currentSwiperHeight = totalHeight;
})
.exec();
},
tabClick(index) {
this.currentIndex = index;
if (this.currentPageScrollTop > 100) {
uni.pageScrollTo({ scrollTop: 100, duration: 100 });
}
if (!this.listData[index] || this.listData[index].length === 0) {
this.getListData(index);
} else {
this.currentSwiperHeight = this.swiperHeightData[index] || 400;
}
},
onSwiperChange(e) {
if (e.detail.source === "touch") {
this.currentIndex = e.detail.current;
}
},
onSwiperEnd() {
const index = this.currentIndex;
if (!this.listData[index] || this.listData[index].length === 0) {
this.getListData(index);
} else {
this.currentSwiperHeight = this.swiperHeightData[index] || 400;
}
},
goToDetail(item) {
uni.navigateTo({
url: "/subpkg/pages/book-detail/book-detail?isbn=" + item.isbn
});
}
}
};
</script>
<style lang="scss" scoped>
.lending-container {
background-color: #f5f5f5;
min-height: 100vh;
.tab-sticky {
position: sticky;
top: 0;
z-index: 99;
background: #fff;
}
.swiper {
width: 100%;
min-height: 300px;
}
.swiper-item {
width: 100%;
height: 100%;
}
.list-wrapper {
padding: 10px;
box-sizing: border-box;
}
.empty {
text-align: center;
padding: 100px 0;
color: #999;
font-size: 14px;
}
}
</style>