vite-plugin-svg4vue
Version:
A vite plugin which can transform svg icon to vue component, support optimization via SVGO, easy to customize svg color and size.
168 lines (124 loc) • 5.78 kB
Markdown
<p align="center">
<a href="https://www.npmjs.org/package/vite-plugin-svg4vue">
<img src="https://img.shields.io/npm/v/vite-plugin-svg4vue.svg">
</a>
<a href="https://npmcharts.com/compare/vite-plugin-svg4vue?minimal=true">
<img src="https://img.shields.io/npm/dm/vite-plugin-svg4vue.svg">
</a>
<br>
</p>
# vite-plugin-svg4vue
A `vite (3.x || 4.x)` plugin which can transform `SVG` icon to `vue (2.7.X || 3.x)` component.
> this plugin dependencies on `vue/compiler-sfc`, so keep your `vue` version to **3.2.13+** or **2.7.14+**.
- [Example Here](https://hongwenqing.com/vite-plugin-svg4vue/).
- [Release Notes](./CHANGELOG.md).
# Features
- [SVGO](https://github.com/svg/svgo) optimization.
- Hot Module Replacement support.
- Support for `?url` , `?component` and `?raw` query string.
- Support custom svg icon (monochrome) color with `fill` , `fill-opacity` , `stroke` , `stroke-opacity` attribute.
- Support change svg icon size with `font-size` and it will be responsive.
- Support <a href="https://www.iconfont.cn/" target="_blank">Iconfont SVG Icons</a>.
# Installation
```bash
# pnpm
$ pnpm add vite-plugin-svg4vue -D
# yarn
$ yarn add vite-plugin-svg4vue --dev
# npm
$ npm i vite-plugin-svg4vue -D
```
# Usage
## Setup
```ts
// vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { svg4VuePlugin } from 'vite-plugin-svg4vue'
export default defineConfig({
plugins: [
vue(),
svg4VuePlugin(),
],
})
```
## In Vue
```vue
<template>
<div>
<h2>SVG component: </h2>
<!-- you can change the svg icon color with `fill` attribute when it's a monochrome icon -->
<LogoSvg fill="red" />
<!-- you can change the svg icon size with `font-size` or `width`. both of this will be responsive -->
<LogoSvg font-size="48" />
<LogoSvg width="48" />
<h2>SVG url: </h2>
<p>
<img :src="logoSvgUrl" alt="" width="36" />
</p>
<h2>SVG raw: </h2>
<p>
<span v-html="logoSvgRaw"></span>
</p>
</div>
</template>
<script setup lang="ts">
import LogoSvg from '@/icons/logo.svg?component'
import logoSvgUrl from '@/icons/logo.svg?url'
import logoSvgRaw from '@/icons/logo.svg?raw'
</script>
```
## Skip SVGO for a single file (Added in v2.8.1)
**SVGO** can be explicitly disabled for one file by adding the `?skipsvgo` query string:
```vue
<template>
<div class="d-flex align-center mb-16">
<label class="mr-12"> ?component&skipsvgo: </label>
<PPTSvg />
</div>
<div class="d-flex align-center">
<label class="mr-12"> ?raw&skipsvgo: </label>
<span v-html="PPTSvgRaw"></span>
</div>
</template>
<script setup lang="ts">
import PPTSvg from '@/icons/ppt.svg?component&skipsvgo'
import PPTSvgRaw from '@/icons/ppt.svg?raw&skipsvgo'
</script>
```
## Typescript
If you are using TypeScript, **vite-plugin-svg4vue/client** can be added to `d.ts` declaration file.
``` ts
/// <reference types="vite-plugin-svg4vue/client" />
```
## Options
| Key | Default value | Description | Type |
| :---: | :---: | :---: | :---: |
| `svgoConfig` | `{}` | [SVGO](https://github.com/svg/svgo) config. if set to `false`, will disable **SVGO**. | `object/boolean` |
| `enableSvgoPresetDefaultConfig` | `true` | Whether to enable `preset-default` configuration for **SVGO** | `boolean` |
| `defaultExport` | `url` | Default behavior when importing `.svg` files, possible options are: `url` , `component` and `raw` | `string` |
| `assetsDirName` | `icons` | Restrict SVG to a specific folder. As long as the SVG is in the `assetsDirName` folder, it can be processed by this plugin, Even if the folder is nested, such as, `path/to/icons/*.svg`, `icons/path/to/svg/*.svg` , ` path/to/icons/path/to/*.svg` and so on. If set `assetsDirname` to `false` , will make it work with arbitrary file path. | `string/boolean` |
| `enableBuildCache` | `true` | Whether to enable caching at build time | `boolean` |
| `enableMonochromeSvgOptimize` | `true` | Whether to enable **monochrome** svg icon optimize which can move child node (named **path**, Even the **path** wrapped by **g**) 's `fill`, `fill-opacity` and `stroke`, `stroke-opacity` attribute to its parent node (**svg** element). So that you can change the svg icon color with `fill` and `stroke`. | `boolean` |
| `enableSvgSizeResponsive` | `true` | Whether to enable svg icon responsive. | `boolean` |
| `namespaceClassnames` | `true` | Whether to add a namespace for `class` selector. | `boolean` |
| `namespaceIDs` | `true` | Whether to add a namespace for `ID` selector. | `boolean` |
| `namespacePrefix` | `'a'` | Whether to add a namespace prefix string for selector. | `string` |
| `enforce` | `'pre'` | Define this plugin invocation order. | `string` or `boolean` |
### What `enableSvgSizeResponsive` do ?
In fact, for the **svg** node, **vite-plugin-svg4vue** will set the `width` value to `font-size`, remove svg `height` and set `width` to `1em`, so that the **svg** size will be **responsive** and you can manipulate it's size with `font-size`.
Just in case, it records the **original size** of the **svg** as a **css variables**:
``` html
<svg style="--svg-origin-width: ${origin width}; --svg-origin-height: ${origin height};"></svg>
```
So, you can easily apply its original size.
```vue
<template>
<LogoSvg fill="red" style="width: var(--svg-origin-width); height: var(--svg-origin-height)" />
</template>
<script setup lang="ts">
import LogoSvg from '@/icons/logo.svg?component'
</script>
```
# Framework Support
- **Nuxt**: see [nuxt-svg-icons](https://github.com/yisibell/nuxt-svg-icons).