我需要检查浏览器是否加载了图像,是否获取了所有数据,然后显示内容,如果没有,则显示<ItemCardSkeleton />
组件。因此,如果一个图像加载速度比其他图像快,我会想要显示内容,其余图像将有一个 backbone ,直到它们一个接一个地完全加载。
我的尝试:我通过添加@load
来检查图像是否被加载,因此如果isLoaded
被设置为true
,则意味着它被加载。然后我检查来自API的数据是否处于挂起状态(我向子组件传递了一个prop),如果isLoaded
是true
,则显示<ItemCardSkeleton />
。
问题:当我把节流设置为2G并重新加载页面时,所有的加载器在几秒钟内同时出现,<ItemCardSkeleton />
无限加载,所以我从来没有看到真实的卡出现。此外,我可以看到模板中的{{ isLoaded }}
总是false
。
父组件ItemSwiper.vue:
<template>
<Swiper>
<template v-for="recipe in storeRecipes.data" :key="recipe.id">
<SwiperSlide class="swiper__slide">
<ItemCard :data="recipe" :pending="storeRecipes.data" />
</SwiperSlide>
<div class="swiper-custom-pagination"></div>
</template>
</Swiper>
</template>
<script setup>
import { onMounted } from 'vue';
import { Swiper, SwiperSlide } from 'swiper/vue';
import { useStoreRecipes } from '@/stores/recipes/storeRecipes.js';
import ItemCard from '@/components/ItemCard.vue';
const storeRecipes = useStoreRecipes();
onMounted(() => {
storeRecipes.loadRecipes();
});
</script>
字符串
子组件ItemCard.vue:
<template>
<div class="card">
<div class="card__item">
<ItemCardSkeleton v-if="pending || !isLoaded" />
<template v-else>
<img
class="card__image"
@load="isLoaded = true"
:src="getSrc('.jpg')"
:alt="data.alt"
width="15.625rem" />
<div class="card__content">
<h2 class="card__title">{{ data.title }}</h2>
<p class="card__text">{{ data.text }}</p>
<router-link class="card__link" :to="{ name: 'Home' }"
>View more</router-link
>
</div>
</template>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue';
import ItemCardSkeleton from '@/components/SkeletonLoaders/ItemCardSkeleton.vue';
const props = defineProps(['data', 'pending']);
const isLoaded = ref(false);
const getSrc = ext => {
return new URL(
`../assets/images/recipe/${props.data.image}${ext}`,
import.meta.url
).href;
};
</script>
型
2条答案
按热度按时间v9tzhpje1#
问题是
isLoaded
必须为真才能呈现<img
,这样isLoaded
才能设置为true
所以,很明显,你有一个不可能的情况,因为
isLoaded
不能被设置为真,直到它已经是真的。为了说明你的代码在做什么,考虑一下:
字符串
正如您所看到的,只有当
isLoaded
已经为真时,isLoaded
才能被设置为真(代码只运行10秒,isLoaded
在此逻辑下永远不会为真尝试以下
从
<img
中删除@load
使用
onMounted
* 预加载图像到new Image
当图像加载时,设置
isLoaded = true
比如说:
型
唯一的问题是,我看不出
pending
是如何变成false
的,但我想这取决于您为了演示上面的类似代码,其他一些代码需要设置
isLoaded = true
(这是在new Image
加载到答案中时完成的,但在这个演示中,只是在5秒后超时)型
bttbmeg02#
如果你想传递一个布尔值来表示数据是否还在加载,你应该在
ItemSwiper.vue
中将:pending="storeRecipes.data"
改为:pending="storeRecipes.pending"
。另外,对于每个新的卡组件,将isLoaded
初始化为false
。ItemSwiper.vue
字符串
ItemCard.vue
型
请确保
getSrc('.jpg')
提供的路径正确。如果路径不正确或镜像加载有任何问题,则不会触发@load
事件,isLoaded
将保持false
。通过这些更改,每张卡将独立控制其自己的加载状态,确保 backbone 加载器显示,直到为每张卡加载数据和图像。