跳到主要内容

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" />
))}