透過 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-icon 組件 由 nuxt-svgo 提供 一樣。

範例

// 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>

運作方式

Vite

如果您的 Nuxt 應用程式使用 Vite,此模組會將 vite-svg-loader 新增至底層的 Vite 配置。所有對 vite-svg-loader 的功勞都歸於其作者 @jpkleemans

我們使用此 vite 外掛程式的修改副本,透過 nuxt-icon 組件進行自動載入圖示以及額外的控制。

Webpack

如果您的 Nuxt 應用程式使用 Webpack,此模組會將 vue-svg-loadersvgo-loader 新增至底層的 Webpack 配置。如 此 issue 中所討論的,vue-svg-loader 使用 SVGO 的版本 1。vue-svg-loader 似乎已停止維護,最新的 beta 版本已超過 2 年。我們停用了 vue-svg-loader 的 SVGO 功能,而是依賴 svgo-loader 來執行最佳化,基本上是讓 vue-svg-loader 將 svg 內容包裝在 <template></template> 標籤中。

所有對 vue-svg-loader 的功勞都歸於其作者 @damianstasik。所有對 svgo-loader 的功勞都歸於其作者 @svg

如果您正在使用 webpack,請確保已安裝此模組的 peer dependencies (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 data 運作所必需的。在某些罕見的情況下,它可能不存在。使用 url_encode 查詢時,請確保它存在,否則圖片將不會顯示。

TypeScript 的使用方式

在 TypeScript 中匯入 SVG 組件時,您會收到 "Cannot find module" 錯誤。為了修正此錯誤,您需要提供類型宣告,以告知 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 的 opinionated default config,為了使其像以前一樣工作,只需將 {} 傳遞給 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

表達您的支持

如果這個專案幫助了您,請給予 ⭐️!

📝 授權條款

Copyright © 2025 Corey Psoinos

此專案以 MIT 授權條款發布。