Recently, the blog wrote that in the project list, I found that there are many pictures here, the loading will be slow, and then I want to use a loading picture to occupy the space. At the same time, if the image fails to load then display the wrong image instead of showing an original error, which is ugly.
The effect
The principle of analytic
If you change the url address of the img tag in vue, vue will update the data in response.
Photo event
Images have a lot of events, for example, onLoad, onError, and so on, and as soon as the image is loaded, the onLoad event will be called, and it will be called whether the image is loaded successfully or failed. And the onError method is called if the image is not displayed. From the comparison of these two methods, we can see that we need to use onLoad to load the image initially, and the image can succeed, can fail, etc.
Component code
import { ImgHTMLAttributes } from "react"; export interface IImagProps<T> extends ImgHTMLAttributes<T> { loadingImg? : string, errorImg? : string, src: string, } import React, { useState } from 'react' import loadImg from './.. /.. /.. /assets/imgs/loading/load.gif'; import errorImg from './.. /.. /.. /assets/imgs/loading/error.png' export default function Img(props: IImagProps<any>) { const [src, setSrc] = useState(props.loadingImg as string) const [isFlag, setIsFlag] = useState(false) const handleOnLoad = () => { if (isFlag) return; const imgDom = new Image(); imgDom.src = props.src; imgDom.onload = function () { setIsFlag(true) setSrc(props.src) } imgDom.onerror = function () { setIsFlag(true) setSrc(props.errorImg as string) } } return ( <> <img src={src} onLoad={handleOnLoad} style={{ height: 'inherit', }} ></img> </> ) } Img.defaultProps = { loadingImg: loadImg, errorImg: errorImg }Copy the code
This article uses the Article Synchronization Assistant to synchronize