NextJS v11 及更高版本
使用 blurDataURL 属性作为占位符,但在将 SVG 转换为 data-uri 之前。
阅读更多关于blurDataURL
? NextJS v11以下版本的解决方案
为避免在占位符之前加载图像,您需要to convert it to data-uri 并将其与您的代码一起交付:
const placeholder = `data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-8 -8 40 40' fill='none' stroke='%23fff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-image'%3E%3Crect x='3' y='3' width='18' height='18' rx='2' ry='2'%3E%3C/rect%3E%3Ccircle cx='8.5' cy='8.5' r='1.5'%3E%3C/circle%3E%3Cpolyline points='21 15 16 10 5 21'%3E%3C/polyline%3E%3C/svg%3E`
<img src={placeholder}/>
现在您需要获取真实图像并为此使用 Image 类:
const [url, setUrl] = useState(placeholder) // use placeholder as default image, which appears instantly
const img = new Image()
img.src = src
img.onload = () => setUrl(img.src) // callback is called when image is loaded, with setUrl we swap images
完整组件:
import './styles.css'
import {useEffect, useState} from 'react'
// to create data url use this service: https://heyallan.github.io/svg-to-data-uri/
const placeholder = `data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-8 -8 40 40' fill='none' stroke='%23fff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-image'%3E%3Crect x='3' y='3' width='18' height='18' rx='2' ry='2'%3E%3C/rect%3E%3Ccircle cx='8.5' cy='8.5' r='1.5'%3E%3C/circle%3E%3Cpolyline points='21 15 16 10 5 21'%3E%3C/polyline%3E%3C/svg%3E`
const Picture = ({alt, src, ...props}) => {
const [url, setUrl] = useState(placeholder)
useEffect(() => {
if (!src) return
const img = new Image()
img.src = src
img.onload = () => setUrl(img.src)
}, [src])
return <img alt={alt} src={url} {...props} />
}
const App = () => (
<div className='App'>
<h1>Hello CodeSandbox</h1>
<Picture
className='img'
alt='Random image'
src='https://picsum.photos/500/500'
/>
</div>
)
☝️ 为避免名称冲突,请导入不同名称的 NextJS Image 组件:
import NextImage from 'next/image' // instead of import Image from 'next/image'
在这里你可以找到the demo。要查看它是如何工作的,请单击刷新图标: