You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Nuxt 3 SSR模式下如何监听图片load事件?求替代方案

Nuxt 3 SSR 模式下监听图片加载状态的解决方案

在 SSR 模式下,图片会在服务端完成渲染,客户端 hydration 阶段不会重复触发 load 事件,导致常规的 onload 监听失效。以下是几种可行的替代方案:

1. 手动检查图片状态 + 事件监听

在客户端挂载后,先判断图片是否已加载完成(利用 img.complete 属性),未完成则绑定 load/error 事件,同时结合 Intersection Observer 优化性能(只监听进入视口的图片)。

示例代码(组件内):

<template>
  <img ref="imageRef" src="/assets/hero.jpg" alt="Hero image" />
</template>

<script setup>
const imageRef = ref(null)
const isImageReady = ref(false)

onMounted(() => {
  const img = imageRef.value
  if (!img) return

  // 先检查是否已加载完成(缓存或SSR预加载)
  if (img.complete) {
    finishLoading()
    return
  }

  // 绑定加载/错误事件
  const handleLoad = () => {
    finishLoading()
    cleanUpEvents()
  }
  const handleError = () => {
    // 加载失败也标记为完成,避免预加载器卡住
    finishLoading()
    cleanUpEvents()
  }

  img.addEventListener('load', handleLoad)
  img.addEventListener('error', handleError)

  // 用Intersection Observer优化:只处理进入视口的图片
  const observer = new IntersectionObserver((entries) => {
    entries.forEach(entry => {
      if (entry.isIntersecting) {
        observer.unobserve(img)
      }
    })
  })
  observer.observe(img)

  function cleanUpEvents() {
    img.removeEventListener('load', handleLoad)
    img.removeEventListener('error', handleError)
  }
})

function finishLoading() {
  isImageReady.value = true
  // 这里写隐藏预加载器的逻辑
  // 比如:document.querySelector('.preloader').classList.add('hidden')
}
</script>

2. 全局监听所有图片加载状态

如果需要等待页面所有图片加载完成再隐藏预加载器,可以在客户端插件中实现:

创建 plugins/client-image-loader.js:

export default defineNuxtPlugin(() => {
  if (process.client) {
    window.addEventListener('DOMContentLoaded', () => {
      const allImgs = document.querySelectorAll('img')
      let loadedCount = 0
      const total = allImgs.length

      if (total === 0) {
        hidePreloader()
        return
      }

      allImgs.forEach(img => {
        if (img.complete) {
          loadedCount++
          checkCompletion()
        } else {
          img.addEventListener('load', () => {
            loadedCount++
            checkCompletion()
          })
          img.addEventListener('error', () => {
            loadedCount++
            checkCompletion()
          })
        }
      })

      function checkCompletion() {
        if (loadedCount === total) hidePreloader()
      }
    })
  }

  function hidePreloader() {
    const preloader = document.querySelector('.global-preloader')
    if (preloader) preloader.style.display = 'none'
  }
})

3. 借助 Nuxt Image 模块(推荐)

如果项目使用 @nuxt/image 模块,它会自动处理 SSR 下的图片加载状态,直接通过组件事件监听即可:

<template>
  <NuxtImg 
    src="/assets/banner.jpg" 
    alt="Banner"
    @load="handleImageLoaded"
    @error="handleImageError"
  />
</template>

<script setup>
function handleImageLoaded() {
  // 图片加载完成,隐藏预加载器
}

function handleImageError() {
  // 处理加载失败逻辑
}
</script>

注意事项

  • 所有监听逻辑必须放在客户端生命周期钩子(如 onMounted)或 process.client 判断内,避免 SSR 阶段执行 DOM 操作。
  • 务必处理 error 事件,防止图片加载失败导致预加载器一直显示。

内容的提问来源于stack exchange,提问作者IninsayY

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 14:01:03