返回

Nuxt.js 3 如何处理图片加载错误?

前端

在 Nuxt.js 3 项目中,我们经常需要处理图片加载错误的情况。当图片加载失败时,我们希望显示备用图片,而不是让用户看到一个破损的图片图标。本文将介绍如何在 Nuxt.js 3 中实现这一功能,确保当图片加载失败时,自动切换到备用图片。

原始问题

在我们最初的实现中,使用了 computed 属性来计算图片的 src 值。然而,当图片加载失败时,更新 src 的方式不能被 Vue 的响应式系统正确检测到,这导致图片组件继续尝试加载旧的 URL,无法正确切换到备用图片。

解决方案:使用 refwatchEffect

为了让 Vue 正确检测到 src 的变化并重新渲染组件,我们可以使用 ref 来存储 src 的值,而不是 computed

步骤详解

  1. 定义 Props

    我们首先定义了两个属性:srcalt

    const props = defineProps({
      src: String,
      alt: String
    });
    
  2. 使用 ref 存储 src 的值

    使用 ref 来存储 src 的值,使 computedSrc 成为一个响应式的引用。当 computedSrc 的值改变时,Vue 会自动检测到并重新渲染组件。

    const computedSrc = ref(props.src === 'undefined' ? getCoverImg() : props.src);
    
  3. 监视 props.src 的变化

    使用 watchEffect 来监视 props.src 的变化。当 props.src 变化时,watchEffect 会重新计算并更新 computedSrc 的值,确保 computedSrc 始终是最新的。

    watchEffect(() => {
      computedSrc.value = props.src === 'undefined' ? getCoverImg() : props.src;
    });
    
  4. 处理图片加载错误

    在图片加载失败时,handleError 会被调用。我们更新 computedSrc 的值为备用图片的 URL,并手动设置 event.target.src 为新的 URL。这一步非常重要,因为它确保了 <NuxtImg> 组件和 DOM 中的 img 元素都使用新的图片 URL。

    const handleError = (event) => {
      // 设置备用图片
      computedSrc.value = getCoverImg();
      event.target.src = computedSrc.value;
    };
    
  5. 完整代码示例

    以下是完整的代码示例,展示了如何在 Nuxt.js 3 中处理图片加载错误并使用备用图片:

    <template>
      <NuxtImg :src="computedSrc" loading="lazy" :alt="alt" @error="handleError" />
    </template>
    
    <script setup>
    import { ref, watchEffect } from 'vue';
    
    // 获取1-42之间的随机数
    function getRandomIntInclusive(min, max) {
      min = Math.ceil(min);
      max = Math.floor(max);
      return Math.floor(Math.random() * (max - min + 1)) + min;
    }
    
    function getCoverImg() {
      return `https://xxx${getRandomIntInclusive(1, 42)}.jpg`;
    }
    
    // 通过 defineProps 定义 props
    const props = defineProps({
      src: String,
      alt: String
    });
    
    // 使用 ref 存储 src 的值
    const computedSrc = ref(props.src === 'undefined' ? getCoverImg() : props.src);
    
    // 监视 props.src 的变化并更新 computedSrc
    watchEffect(() => {
      computedSrc.value = props.src === 'undefined' ? getCoverImg() : props.src;
    });
    
    // 处理图片加载错误
    const handleError = (event) => {
      // 设置备用图片
      computedSrc.value = getCoverImg();
      event.target.src = computedSrc.value;
    };
    </script>
    

总结

通过使用 refwatchEffect,我们确保图片的 src 值在任何时候都能被 Vue 正确地检测到和更新。这解决了当图片加载失败时旧的 URL 仍然被使用的问题。

简单来说:

  • ref 提供了响应式存储,确保任何时候 src 的变化都能被 Vue 监测到。
  • watchEffect 确保 src 值变化时自动更新。
  • handleError 更新 src 为备用图片的 URL,并确保组件和 DOM 都正确使用新的 URL。