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 元件時,您會收到“找不到模組”錯誤。為了解決這個問題,您應該在模組配置中啟用 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 模組 複製而來,但後來經過大量修改以支援 Tree Shaking 和 SSR。不建議直接使用。但是,您可以直接匯入圖示並透過 icon
prop 將它們傳遞給元件。
元件屬性
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
表達您的支援
如果此專案對您有幫助,請給個 ⭐!
📝 許可證
版權所有 © 2025 Corey Psoinos。
本專案採用 MIT 許可證。