为什么 Vue 3 不重新渲染 <img>,即使它重新渲染组件中的其他所有内容?

问题描述 投票:0回答:1

我正在开发一个 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 有正确的图像,因为它没有上次遗留下来的图像。这让我相信这是某种缓存问题,但我不知道如何覆盖它。向图像添加关键点似乎不起作用。

javascript node.js vue.js vuejs3 vue-component
1个回答
0
投票

您可以使用

@error
指令在 Vue 中指定替代图像,无需使用单独的函数检查图像是否存在:

<img :src="imgUrl" @error="$event.target.src='/img/story/contents/000000.gif'"/>

或者,如果您仍然想这样做,则无需在此处调用

onMounted
钩子,您可以创建一个自调用函数。例如

(function () {
  // logic
})();

// OR
const f = () => {
  // logic
}

f();
© www.soinside.com 2019 - 2024. All rights reserved.