nuxt-svgonuxt-svgo 是一个 Nuxt 模块,用于将优化后的 SVG 文件作为 Vue 组件加载。
在 StackBlitz 上试用!
npx nuxi@latest module add nuxt-svgo
通过将 'nuxt-svgo' 添加到 Nuxt 配置的 modules 部分来使用默认配置。
// nuxt.config.ts
import { defineNuxtConfig } from 'nuxt'
export default defineNuxtConfig({
modules: ['nuxt-svgo'],
})
然后,在任何 .vue 文件中,导入您的资源并将其用作组件
<template>
<div>
<!-- font size controls width & height by default: -->
<IconHome class="text-xl" />
<!-- you can disable it: -->
<IconHome class="w-5 h-5" :fontControlled="false" />
</div>
</template>
<script setup lang="ts">
import IconHome from '~/assets/icon-home.svg'
</script>
或者,如果您使用 vite,在任何 .vue 文件中,只需使用您的图标名称,并带上 svgo 前缀作为组件名称
<template>
<div>
<SvgoHome class="text-xl" />
<!-- Or -->
<svgo-home class="text-xl" />
</div>
</template>
它默认会自动从 assets/icons/ 文件夹导入您的图标。您可以通过在配置中传递 autoImportPath 来配置此项
// nuxt.config.ts
import { defineNuxtConfig } from 'nuxt'
export default defineNuxtConfig({
modules: ['nuxt-svgo'],
svgo: {
autoImportPath: './assets/other-icons/',
},
})
如果您想使用自动导入,但又不想使用 nuxt-icon 组件(默认使用),您可以通过使用 defaultImport: 'component' 来实现
// nuxt.config.ts
import { defineNuxtConfig } from 'nuxt'
export default defineNuxtConfig({
modules: ['nuxt-svgo'],
svgo: {
defaultImport: 'component',
},
})
您还可以使用自己的自定义组件,而不是内置的 nuxt-icon 组件,通过使用 customComponent 选项。此自定义组件必须具有 icon 属性,就像 nuxt-svgo 提供的 nuxt-icon 组件一样。
示例
// nuxt.config.ts
import { defineNuxtConfig } from 'nuxt'
export default defineNuxtConfig({
modules: ['nuxt-svgo'],
svgo: {
customComponent: 'YourComponent',
},
})
默认情况下,模块会将 autoImportPath 内部的所有图标全局注册。这可能是不需要的行为,因为它会为每个全局使用的图标生成 chunk,如果您有大量图标,这将导致大量文件。如果您想禁用全局注册,只需在模块选项中设置 global: false
// nuxt.config.ts
import { defineNuxtConfig } from 'nuxt'
export default defineNuxtConfig({
modules: ['nuxt-svgo'],
svgo: {
global: false,
},
})
要禁用自动导入,只需将 autoImportPath 设置为 false
// nuxt.config.ts
import { defineNuxtConfig } from 'nuxt'
export default defineNuxtConfig({
modules: ['nuxt-svgo'],
svgo: {
autoImportPath: false,
},
})
图标的组件名称将遵循 Nuxt 的组件前缀约定。因此,如果您的组件已开启前缀,则 assets/icons/admin/badge.svg 的组件名称将为 svgo-admin-badge
<svgo-admin-badge />
componentPrefix您可以使用 componentPrefix 选项将默认前缀 (svgo) 更改为您的自定义前缀
// nuxt.config.ts
import { defineNuxtConfig } from 'nuxt'
export default defineNuxtConfig({
modules: ['nuxt-svgo'],
svgo: {
componentPrefix: 'i',
},
})
// in your template
<template>
<div>
<i-home />
</div>
</template>
如果您的 Nuxt 应用程序使用 Vite,此模块会将 vite-svg-loader 添加到底层的 Vite 配置中。所有 vite-svg-loader 的功劳归其作者 @jpkleemans。
我们使用此 vite 插件的修改副本,通过 nuxt-icon 组件进行额外控制,实现图标的自动加载。
如果您的 Nuxt 应用程序使用 Webpack,此模块会将 vue-svg-loader 和 svgo-loader 添加到底层的 Webpack 配置中。正如 此问题 中所讨论的,vue-svg-loader 使用 SVGO 的版本 1。vue-svg-loader 似乎没有维护,最新的测试版已超过 2 年。我们禁用 vue-svg-loader 的 SVGO 功能,而是依赖 svgo-loader 进行优化,本质上使 vue-svg-loader 将 svg 内容包装在 <template></template> 标签中。
所有 vue-svg-loader 的功劳归其作者 @damianstasik。所有 svgo-loader 的功劳归其作者 @svg。
如果您正在使用 webpack,请确保安装了此模块的对等依赖项(vue-svg-loader、svgo-loader、vue-loader)。
使用您自己的自定义 SVGO 选项
// nuxt.config.ts
import { defineNuxtConfig } from 'nuxt'
export default defineNuxtConfig({
modules: ['nuxt-svgo'],
svgo: {
svgoConfig: {
multipass: true,
plugins: [
{
name: 'preset-default',
params: {
overrides: {
// customize default plugin options
inlineStyles: {
onlyMatchedOnce: false,
},
// or disable plugins
removeDoctype: false,
removeViewBox: false,
},
},
},
],
},
},
})
完全禁用 SVGO
// nuxt.config.ts
import { defineNuxtConfig } from 'nuxt'
export default defineNuxtConfig({
modules: ['nuxt-svgo'],
svgo: {
svgo: false,
},
})
以下是导入 SVG 文件时可能的查询
url_encode:将优化后的 svg 作为数据 URI 加载(使用 svgo + mini-svg-data-uri)raw:将内容作为文本加载raw_optimized:将优化后的 svg 作为文本加载skipsvgo:将内容作为组件加载(未优化,不带 nuxt-icon)component:将优化后的 svg 作为组件加载componentext:使用 nuxt-icon 组件加载优化后的 svg例如
<template>
<div>
<IconHome />
</div>
</template>
<script setup lang="ts">
import IconHome from '~/assets/icon-home.svg?componentext' // the default
</script>
url_encode 查询的重要提示xmlns="http://www.w3.org/2000/svg" 属性对于 URI 数据生效是必需的。在某些罕见情况下,它可能不存在。使用 url_encode 查询时请确保它存在,否则图像将不会显示。
在 TypeScript 中导入 SVG 组件时,您将收到“找不到模块”错误。为了解决此问题,您应该在模块配置中启用 dts 选项。这将自动为 SVG 导入生成 TypeScript 声明文件。仅适用于 nuxt-svgo v4.1.0 及以上版本。
export default defineNuxtConfig({
// ...
svgo: {
dts: true,
},
})
如果您使用的模块版本低于 v4.1.0,您需要手动提供类型声明,以告诉 TypeScript 如何处理 SVG 组件。以下是一个示例,使用应用程序根目录下的 custom.d.ts 文件
// custom.d.ts
declare module '*.svg' {
import type { DefineComponent } from 'vue'
const component: DefineComponent
export default component
}
nuxt-icon 组件最初从 nuxt-icons 模块 复制过来,但后来经过大量修改以支持摇树优化和 SSR。它不适合直接使用。但是,您可以直接导入图标,并使用 icon 属性将它们传递给组件。
filled:当 true 时使用图标的原始颜色fontControlled:您可以通过将此属性设置为 false 来禁用按字体大小缩放的默认行为icon:nuxt-icon 将渲染为的组件。这在内部用于控制图标。如果您之前使用 nuxt-icon 组件,您必须像这样更改您的代码
<!-- from: -->
<nuxt-icon name="home" filled />
<nuxt-icon name="special/home" filled />
<!-- to: -->
<svgo-home filled />
<svgo-special-home filled />
v3 现在默认使用一个有主见的 SVGO 默认配置,要使其像以前一样工作,只需将 {} 传递给 svgoConfig 选项
export default defineNuxtConfig({
// ...
svgo: {
svgoConfig: {},
},
})
此外,自 v3 起,simpleAutoImport 选项已移除,defaultImport 已更改为 componentext。如果您之前使用以下代码并依赖 defaultImport,请更改它
<template>
<div>
<IconHome class="text-xl" />
</div>
</template>
<script setup lang="ts">
// change this:
import IconHome from '~/assets/icon-home.svg'
// to this:
import IconHome from '~/assets/icon-home.svg?component'
</script>
pnpm dev:prepare 以生成类型存根。pnpm dev 在开发模式下启动 playground。Corey Psoinos
Javad Mnjd
如果此项目对您有帮助,请给个 ⭐️!
版权所有 © 2025 Corey Psoinos。
本项目采用 MIT 许可证。