|
@@ -24,7 +24,11 @@
|
|
|
<div class="collections-main">
|
|
|
<Menu />
|
|
|
|
|
|
- <div v-loading="loading" class="collections-main__right">
|
|
|
+ <div
|
|
|
+ v-loading="loading"
|
|
|
+ element-loading-background="rgba(122, 122, 122, 0.8)"
|
|
|
+ class="collections-main__right"
|
|
|
+ >
|
|
|
<Waterfall :list="list" :gutter="30" :hasAroundGutter="false">
|
|
|
<template #item="{ item, url }">
|
|
|
<div
|
|
@@ -32,7 +36,12 @@
|
|
|
aria-label="Link"
|
|
|
@click="handleItemClick(item)"
|
|
|
>
|
|
|
- <img alt="" :src="url" aria-label="Image link" />
|
|
|
+ <img
|
|
|
+ alt=""
|
|
|
+ :src="url"
|
|
|
+ aria-label="Image link"
|
|
|
+ :style="{ height: item.imgHeight + 'px' }"
|
|
|
+ />
|
|
|
<div class="collections-item__inner">
|
|
|
<p tabindex="0" :aria-description="item.name">
|
|
|
{{ item.name }}
|
|
@@ -46,6 +55,10 @@
|
|
|
</Waterfall>
|
|
|
|
|
|
<p v-if="noData" class="no-more">no more</p>
|
|
|
+
|
|
|
+ <div v-if="rendering && pageNum > 1" style="text-align: center">
|
|
|
+ <VanLoading color="var(--van-primary-color)" />
|
|
|
+ </div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
@@ -56,9 +69,8 @@
|
|
|
|
|
|
<script lang="ts" setup>
|
|
|
import { Waterfall } from "vue-waterfall-plugin-next";
|
|
|
-import type { ViewCard } from "vue-waterfall-plugin-next/dist/types/types/waterfall";
|
|
|
import { useRoute } from "vue-router";
|
|
|
-import { computed, ref, watch } from "vue";
|
|
|
+import { computed, onBeforeUnmount, onMounted, ref, watch } from "vue";
|
|
|
import { getBaseURL } from "@dage/service";
|
|
|
import { useBaseStore } from "@/stores/base";
|
|
|
import Breadcrumb from "@/components/Breadcrumb/index.vue";
|
|
@@ -83,11 +95,19 @@ const curRoute = computed(() =>
|
|
|
);
|
|
|
const visible = ref(false);
|
|
|
const checkedItemId = ref<number | null>(null);
|
|
|
+// 当前页图片数据是否全部加载完成
|
|
|
+const rendering = ref(false);
|
|
|
+const list = ref<any[]>([]);
|
|
|
+const loading = computed(
|
|
|
+ () => (rendering.value || fetchLoading.value) && pageNum.value === 1
|
|
|
+);
|
|
|
|
|
|
const {
|
|
|
+ pageNum,
|
|
|
list: sourceList,
|
|
|
noData,
|
|
|
- loading,
|
|
|
+ noMore,
|
|
|
+ loading: fetchLoading,
|
|
|
resetParams,
|
|
|
getList,
|
|
|
} = usePagination<CollectionListItem>(
|
|
@@ -100,23 +120,77 @@ const {
|
|
|
PaginationType.DEFAULT,
|
|
|
20
|
|
|
);
|
|
|
-const list = computed<any>(() =>
|
|
|
- sourceList.value.map((i: CollectionListItem) => ({
|
|
|
- ...i,
|
|
|
- src: baseUrl + i.thumb,
|
|
|
- }))
|
|
|
-);
|
|
|
|
|
|
const handleItemClick = (item: any) => {
|
|
|
checkedItemId.value = item.id;
|
|
|
visible.value = true;
|
|
|
};
|
|
|
|
|
|
+const getImgRatio: (url: string) => Promise<number> = (url: string) => {
|
|
|
+ return new Promise((res) => {
|
|
|
+ const img = new Image();
|
|
|
+ img.src = url;
|
|
|
+ img.onload = () => {
|
|
|
+ const ratio = Math.round((img.height / img.width) * 100) / 100;
|
|
|
+ res(ratio);
|
|
|
+ };
|
|
|
+ img.onerror = () => {
|
|
|
+ res(0);
|
|
|
+ };
|
|
|
+ });
|
|
|
+};
|
|
|
+
|
|
|
+const handleScroll = () => {
|
|
|
+ // 检查用户是否滚动到页面底部
|
|
|
+ if (
|
|
|
+ window.innerHeight + window.scrollY >= document.body.offsetHeight &&
|
|
|
+ !rendering.value &&
|
|
|
+ !loading.value &&
|
|
|
+ !noMore.value
|
|
|
+ ) {
|
|
|
+ console.log("Scrolled to bottom");
|
|
|
+ pageNum.value += 1;
|
|
|
+ getList();
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+onMounted(() => {
|
|
|
+ window.addEventListener("scroll", handleScroll);
|
|
|
+});
|
|
|
+
|
|
|
+onBeforeUnmount(() => {
|
|
|
+ window.removeEventListener("scroll", handleScroll);
|
|
|
+});
|
|
|
+
|
|
|
+watch(sourceList, (v) => {
|
|
|
+ if (!v.length) return;
|
|
|
+
|
|
|
+ rendering.value = true;
|
|
|
+
|
|
|
+ const promises = v.map(async (i) => {
|
|
|
+ const url = baseUrl + i.thumb;
|
|
|
+ const ratio = await getImgRatio(url);
|
|
|
+
|
|
|
+ list.value.push({
|
|
|
+ ...i,
|
|
|
+ imgHeight: 303 * ratio,
|
|
|
+ src: url,
|
|
|
+ });
|
|
|
+
|
|
|
+ return i;
|
|
|
+ });
|
|
|
+
|
|
|
+ Promise.allSettled(promises).then(() => {
|
|
|
+ rendering.value = false;
|
|
|
+ });
|
|
|
+});
|
|
|
+
|
|
|
watch(
|
|
|
route,
|
|
|
() => {
|
|
|
if (route.name !== "Collections") return;
|
|
|
|
|
|
+ list.value = [];
|
|
|
resetParams();
|
|
|
getList();
|
|
|
},
|