最近博客写道项目列表中,发现这里比较多图片,一开加载会比较慢,然后就想要用一个loading的图片来占位。与此同时,如果图片加载失败那么显示错误的图片,不显示一个原有的错误,那样比较难看。
效果
原理解析
这个就是一个组件,一个图片展示的组件,直接更改img标签的url地址就好,对的,是这样的,在vue中直接更改地址,vue会有响应式的更新数据。
图片的事件
图片是有许多的事件的,例如,onload, onerror等,图片只要一加载就会调用onload的事件,不管是加载成功还是加载失败都会调用这个方法。而onerror方法是图片在没有显示出来就会调用这个方法。从这两个方法对比可以得知,我们需要使用onload来一开始加载图片,并且图片可以成功,可以失败等。
组件代码
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; // 创建一个img标签 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 }