SVG
2023年12月18日
一、组件加载
1.1 认识
SVG
组件加载在不同的前端框架中的实现不太相同,社区中也已经了有了对应的插件支持:
-
Vue2
项目中可以使用vite-plugin-vue2-svg
插件 -
Vue3
项目中可以引入vite-svg-loader
-
React
项目使用vite-plugin-svgr
插件。
1.2 安装插件
pnpm i vite-plugin-svgr -D
1.3 vite.config.ts 配置
// vite.config.ts
import svgr from 'vite-plugin-svgr';
{
plugins: [
// 其它插件省略
svgr()
]
}
1.4 tsconfig.json 配置
注意要在 tsconfig.json
添加如下配置,否则会有类型错误:
{
"compilerOptions": {
// 省略其它配置
"types": ["vite-plugin-svgr/client"]
}
}
1.5 项目中使用 svg 组件
import ReactLogo from "./assets/react.svg?react";
function App() {
return <div className="">
<ReactLogo color="red"/>
</div>;
}
export default App;
二、雪碧图加载
把一些 svg
合并到一起, 这种合并图标的方案也叫雪碧图, 可以通过 vite-plugin-svg-icons
来实现。通过雪碧图的方式, 就能将所有的 svg
内容都内联到 HTML
中,省去了大量 svg
的网络请求。
2.1 安装
pnpm i vite-plugin-svg-icons -D
2.2 配置
// vite.config.ts
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons';
{
plugins: [
// 省略其它插件
createSvgIconsPlugin({
iconDirs: [path.join(__dirname, 'src/assets/icons')]
})
]
}
2.3 入口文件引入
在src/main.tsx
文件中添加一行代码
import 'virtual:svg-icons-register';
2.4 创建 SvgIcon 组件
// SvgIcon/index.tsx
export interface SvgIconProps {
name?: string;
prefix: string;
color: string;
[key: string]: string;
}
export default function SvgIcon({
name,
prefix = 'icon',
color = '#333',
...props
}: SvgIconProps) {
const symbolId = `#${prefix}-${name}`;
return (
<svg {...props} aria-hidden="true">
<use href={symbolId} fill={color} />
</svg>
);
}
2.5 使用 SvgIcon 组件
// index.tsx
const icons = import.meta.globEager('../../assets/icons/logo-*.svg');
const iconUrls = Object.values(icons).map((mod) => {
// 如 ../../assets/icons/logo-1.svg -> logo-1
const fileName = mod.default.split('/').pop();
const [svgName] = fileName.split('.');
return svgName;
});
// 渲染 svg 组件
{iconUrls.map((item) => (
<SvgIcon name={item} key={item} width="50" height="50" />
))}