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
相关产品推荐
相关产品推荐

