1. 直接导入静态图片(PNG/JPG)
最常见的方式,使用 ES6 import 直接导入:
// 示例: import ADDIMG from '@/asset/img/add-img.png'; import DeleteIcon from '@/asset/img/delete-normal.png'; // 使用 <img src={ADDIMG} alt="add" />特点:
适用于 PNG、JPG 等位图
导入后获得图片 URL
支持路径别名 @/asset/
2. SVG 作为 React 组件导入
使用 vite-plugin-svgr 将 SVG 转为 React 组件:
// 示例:src/App.tsx import { ReactComponent as AssetSvg } from '@/asset/asset-svg.svg'; // 使用 <AssetSvg />特点:
可像组件一样使用
支持 props 传递
适合需要交互的 SVG
3. SVG Sprite 系统(主要方式)
项目使用 SVG Sprite 优化 SVG 加载:
3.1 SVG Sprite 生成
createSvgIcon.js
/** * 将asset/svg下的svg图生成svg雪碧图,减少请求 * vite-plugin-svg-icons原本在vite.config中使用,但是项目启动时每次都会转换,效率很低,影响项目启动,所以用手动的方式生成好雪碧图,直接挂载dom上使用。 * 使用方式:当asset/svg下的图发生变化时(修改、新增、删除),执行npm脚本 yarn build:svg即可 */ const fs = require('fs'); const path = require('path'); const { createSvgIconsPlugin } = require('vite-plugin-svg-icons'); // 配置参数 const config = { iconDirs: [path.resolve(process.cwd(), 'src/asset/svg')], symbolId: 'aseet-svg-[dir]-[name]', // svgoOptions: true, }; // 创建插件实例 const plugin = createSvgIconsPlugin(config); plugin.configResolved({ command: 'build' }); plugin.load('virtual:svg-icons-register').then((res) => { const svgRegex = /svgDom\.innerHTML\s*=\s*"([\s\S]*?)"\s*;\s*body\.insertBefore/; const svgString = res .match(svgRegex)[1] .replace(/\\"/g, '"') .replace(/\\n/g, '') .replace(/\\/g, ''); const svgDom = '<svg id="__svg__icons__dom__" xmlns="http://www.w3.org/2000/svg" xmlns:link="http://www.w3.org/1999/xlink" style="position: absolute; width: 0px; height: 0px;">' + svgString + '</svg>'; fs.writeFileSync('src/asset/asset-svg.svg', svgDom); });3.2 SVG Sprite 加载
App.tsx
try { Object.values(import.meta.glob('/src/asset/svg/**/*.svg', { eager: true })); } catch (error) { console.info('导入svg图片失败', error); }在 App.tsx 中批量导入所有 SVG 文件,生成 Sprite。
3.3 SvgIcon 组件使用
index.tsx
import './index.less'; import classNames from 'classnames'; import type { FC } from 'react'; import React from 'react'; type Props = { src: string; className?: string; style?: any; alt?: string; width?: number | string; height?: number | string; onClick?: () => void; }; const SvgIcon: FC<Props> = ({ src, className, style, width, height, onClick }) => { return ( <svg className={classNames('asset-svg', `asset-svg-${src}`, className)} style={style} onClick={() => onClick?.()} > <use href={'#asset-svg-' + src} width={width} height={height} /> </svg> ); }; export default SvgIcon;使用方式:
// 示例 <SvgIcon src={`interfaces-${typeDesc}-${typeDesc}_${stateDesc}`} className={className} />特点:
所有 SVG 合并为一个文件,减少请求
通过 <use href="#id"> 引用
ID 格式:asset-svg-[dir]-[name]
支持样式和事件
4. CSS/Less 中引用图片
在样式文件中使用 url() 引用:
// 示例: background-image: url('@/asset/img/login-background.png');
特点:
支持路径别名 @/asset/
适合背景图、图标等
有专门的 used-in-css 目录存放 CSS 用图
5. 动态图片 URL(API 获取)
从后端 API 获取图片 URL:
path.url = `${path.url}?tempid=${Math.random()}`; // 解决浏览器缓存img src问题特点:
图片 URL 来自 API
通过添加随机参数避免缓存
用于图库、设备图片等动态内容
6. 内联 SVG 组件
直接在组件中定义 SVG:
index.tsx
export const iconSvg = () => ( <svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M12.9764 6.58129H10.3663L12.1583 4.78926C12.3116 4.62473 12.307 4.36848 12.1481 4.20957C11.9891 4.05066 11.7328 4.04613 11.5684 4.19941L9.18641 6.58129H7.41109V4.80598L9.79297 2.4241C9.94625 2.25973 9.94172 2.00332 9.78281 1.84441C9.62391 1.68535 9.3675 1.68098 9.20312 1.8341L7.41109 3.62613V1.01613C7.41109 0.785664 7.22422 0.598633 6.99375 0.598633C6.76328 0.598633 6.57641 0.785508 6.57641 1.01613V3.62613L4.78438 1.8341C4.61984 1.68082 4.36359 1.68535 4.20469 1.84441C4.04578 2.00332 4.04125 2.25957 4.19453 2.4241L6.57641 4.80598V6.58129H4.80109L2.41906 4.19926C2.25469 4.04598 1.99828 4.05051 1.83938 4.20941C1.68031 4.36832 1.67594 4.62457 1.82906 4.7891L3.62109 6.58113H1.01109C0.780625 6.58113 0.59375 6.76801 0.59375 6.99848C0.59375 7.22895 0.780625 7.41582 1.01109 7.41582H3.62109L1.82922 9.20801C1.77441 9.25912 1.73436 9.32404 1.71327 9.39596C1.69219 9.46787 1.69084 9.54414 1.70937 9.61676C1.7279 9.68936 1.76563 9.75563 1.81861 9.80861C1.87159 9.8616 1.93787 9.89933 2.01047 9.91785C2.15828 9.95566 2.315 9.90973 2.41906 9.79801L4.80094 7.41613H6.57625V9.19145L4.19453 11.5733C4.1397 11.6244 4.09963 11.6893 4.07855 11.7612C4.05746 11.8331 4.05612 11.9093 4.07469 11.9819C4.09323 12.0545 4.13098 12.1208 4.18395 12.1737C4.23693 12.2267 4.30319 12.2645 4.37578 12.283C4.52359 12.3208 4.68031 12.2749 4.78438 12.1632L6.57641 10.3711V12.9813C6.57641 13.2118 6.76328 13.3986 6.99375 13.3986C7.22422 13.3986 7.41109 13.2118 7.41109 12.9813V10.3711L9.20312 12.1632C9.36766 12.3164 9.62391 12.3119 9.78281 12.153C9.94172 11.9939 9.94625 11.7377 9.79297 11.5733L7.41109 9.19129V7.41598H9.18641L11.5683 9.79785C11.7327 9.95113 11.9891 9.9466 12.148 9.7877C12.3069 9.62879 12.3114 9.37254 12.1581 9.20801L10.3663 7.41598H12.9764C13.2069 7.41598 13.3938 7.2291 13.3938 6.99863C13.3938 6.76816 13.2069 6.58129 12.9764 6.58129Z" fill="currentColor" /> </svg> );
特点:
适合简单、固定的 SVG 图标
可直接控制样式和属性
无需额外文件
图片资源目录结构:
使用建议
SVG 图标:优先使用 SvgIcon 组件 + SVG Sprite
位图图片:直接 import PNG/JPG
背景图:在 Less 中使用 url()
动态图片:从 API 获取 URL
简单 SVG:可内联定义
注意事项
SVG Sprite 更新:修改 src/asset/svg/ 下的 SVG 后,需运行 yarn build:svg 重新生成 Sprite
路径别名:统一使用 @/asset/ 路径别名
缓存问题:动态图片 URL 添加随机参数避免缓存
CSS 用图:放在 used-in-css 目录,便于管理