nuxt-svgo
nuxt-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
内的所有图标。这可能是不希望的行为,因为它会为每个全局使用的图标生成代码块,如果你有很多图标,这会导致大量文件。如果你想禁用全局注册,只需在模块选项中使用 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>
它是如何工作的
Vite
如果你的 Nuxt 应用使用 Vite,此模块会将 vite-svg-loader 添加到底层 Vite 配置中。所有关于 vite-svg-loader
的功劳都归于它的作者 @jpkleemans。
我们使用此 vite 插件的修改副本,用于自动加载图标,并通过 nuxt-icon
组件进行额外的控制。
Webpack
如果你的 Nuxt 应用使用 Webpack,此模块会将 vue-svg-loader 和 svgo-loader 添加到底层 Webpack 配置中。如 此问题中所讨论的,vue-svg-loader
使用 SVGO 的版本 1。vue-svg-loader
似乎没有维护,最新的 beta 版本已经两年多前了。我们禁用了 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,
},
})
导入查询 (仅限 Vite.js)
以下是导入 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
查询的重要说明
uri 数据需要 xmlns="http://www.w3.org/2000/svg"
属性。在某些罕见情况下,它可能不存在。请确保在使用 url_encode
查询时它存在,否则将不会显示图像。
与 TypeScript 一起使用
在 TypeScript 中导入 SVG 组件时,你会收到“找不到模块”错误。为了解决这个问题,你需要提供类型声明来告诉 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 模块复制而来,但后来经过大量修改以支持 tree shaking 和 SSR。这不打算直接使用。但是,你可以直接导入你的图标,并使用 icon
prop 将它们传递给组件。
组件 props
filled
:当true
时使用图标的原始颜色fontControlled
:你可以通过将此 prop 设置为false
来禁用默认的字体大小缩放行为icon
:nuxt-icon
将呈现为的组件。这在内部用于提供对图标的控制。
从 v1.x 迁移到 v2.x
如果你之前使用过 nuxt-icon
组件,则必须像这样更改你的代码
<!-- from: -->
<nuxt-icon name="home" filled />
<nuxt-icon name="special/home" filled />
<!-- to: -->
<svgo-home filled />
<svgo-special-home filled />
从 v2.x 迁移到 v3.x
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
- Github: @cpsoinos
Javad Mnjd
- Github: @jd1378
表达你的支持
如果这个项目帮助了你,请给一个 ⭐️!
📝 许可证
版权所有 © 2024 Corey Psoinos。
此项目已获得 MIT 许可。