我正在开发一个 Vue 项目,其中多个链接卡 (
<a class='card'></a>
) 堆叠在一个“甲板”(<div class='deck'></div>
) 内。这些的设置大多非常简单:
<script setup>
const { cardData } = defineProps({
cardData: {
type: Object,
required: true
}
});
</script>
<template>
<RouterLink class="card" :to="`/read/?id=${cardData.content_id}&v=${cardData.content_version}`">
<CardImage :imageData="cardData" />
<div class="card__text">
<h3 v-html="cardData.content_title"></h3>
<p>{{ cardData.content_snippet }}</p>
<div v-if="cardSize == 'small__card'" class="card__details">
<p>Word Count: {{ cardData.content_words }}</p>
</div>
</div>
</RouterLink>
</template>
当您单击其中一张卡片时,下一页上很可能也会有许多卡片 - 所以假设您在一个包含卡片 A、B 和 C 的页面上,然后单击 C,然后您将进入包含卡片 C1、C2、C3... 等的页面。在大多数情况下,这工作得很好!卡中的所有数据都会更新。
除了图像。我所做的一切都没有使图像正确更新,即使我将其设置为基本上与此完全相同的方式也是如此。
图像确实需要一些异步设置,因为我想在尝试渲染卡片之前确保卡片的图像存在。这就是我现在所拥有的:
<script setup>
import { ref, onMounted } from 'vue';
const { imageData } = defineProps({
imageData: {
type: Object,
required: true,
}
});
const imgUrl = ref('');
async function checkIfImageExists(pathID) {
let path = `/img/story/contents/${pathID}.webp`;
const response = await fetch(path);
if (response.status === 200) {
imgUrl.value = path;
} else {
imgUrl.value = `/img/story/contents/000000.gif`;
}
}
onMounted(async () => {
await checkIfImageExists(imageData.content_id);
});
</script>
<template>
<img :src="imgUrl" :alt="imageData.content_id">
</template>
这非常有效......一次。在第一页上,我将获得卡片 A、B 和 C,所有卡片都带有相应的图像……但这些图像不会更新。如果我移至 C 页,我将看到 C1、C2 和 C3 带有 文本 的卡片,但 A、B 和 C 分别带有图像。
我在这里缺少什么吗?我对 Vue 还很陌生,但我花了几天时间专注于教程,感觉我已经很好地掌握了基础知识。我也花了几个小时仔细阅读 Stack Overflow 对类似问题的回答,但我找不到任何人遇到这个确切的问题,所以我无法找到确切的解决方案。
CardImage 最初并不是它自己的组件,但我将其移至一个组件,希望它能够更好地单独处理异步获取。正如我所提到的,它确实可以工作一次,但之后就再也不会了。观察路线变化也无济于事,即使这会触发卡数据的其余部分发生变化。
编辑: 可能值得注意的是,这个问题仅适用于“新”卡。如果第一页有 A、B、C 和 D,然后我在 C1、C2 和 C3 的卡片上看到 A、B 和 C 的图像,当我导航back 到第一页时,D will 有正确的图像,因为它没有上次遗留下来的图像。这让我相信这是某种缓存问题,但我不知道如何覆盖它。向图像添加关键点似乎不起作用。
您可以使用
@error
指令在 Vue 中指定替代图像,无需使用单独的函数检查图像是否存在:
<img :src="imgUrl" @error="$event.target.src='/img/story/contents/000000.gif'"/>
或者,如果您仍然想这样做,则无需在此处调用
onMounted
钩子,您可以创建一个自调用函数。例如
(function () {
// logic
})();
// OR
const f = () => {
// logic
}
f();