通过 100 多个技巧学习 Nuxt!

nuxt-svgo
nuxt-svgo

Nuxt 模块,用于加载优化后的 SVG 文件作为 Vue 组件

nuxt-svgo

npm versionnpm downloadslicense

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-loadersvgo-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-loadersvgo-loadervue-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 来禁用默认的字体大小缩放行为
  • iconnuxt-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

Javad Mnjd

表达你的支持

如果这个项目帮助了你,请给一个 ⭐️!

📝 许可证

版权所有 © 2024 Corey Psoinos

此项目已获得 MIT 许可。