透過 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 看來已經不再維護,最新的測試版本已超過 2 年。我們停用 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 作為 data uri 載入 (使用 svgo + mini-svg-data-uri)
  • raw: 將內容載入為文字
  • raw_optimized: 將最佳化的 svg 載入為文字
  • skipsvgo: 將內容載入為元件 (未最佳化,不含 nuxt-icon)
  • component: 將最佳化的 svg 載入為元件
  • componentext: 將最佳化的 svg 與 nuxt-icon 元件一起載入

例如

<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

Javad Mnjd

表達您的支持

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

📝 授權

版權 © 2024 Corey Psoinos

此專案採用 MIT 授權。