nuxt-svgo
nuxt-svgo
是一个 Nuxt 模块,用于将优化的 SVG 文件加载为 Vue 组件。
在 StackBlitz 上试用!
安装
npx nuxi@latest module add nuxt-svgo
使用
通过在 Nuxt 配置文件的 modules
部分添加 'nuxt-svgo'
来使用 默认配置。
// 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-icon
组件一样 nuxt-svgo 提供的。
示例
// 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,请确保安装此模块的 peer 依赖项(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 加载为 data 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 结合使用
在 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
属性。
组件属性
filled
:当true
时,使用图标的原始颜色fontControlled
:您可以通过将此属性设置为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 许可的。