透過 100+ 個技巧的合輯學習 Nuxt!

icon
@nuxt/icon

適用於 Nuxt 的 Icon 模組,提供來自 Iconify 的 200,000+ 個隨時可用的圖示。

nuxt-icon

Nuxt Icon

npm versionnpm downloadsLicenseNuxtVolta board

200,000+ 個隨時可用的圖示新增至您的 Nuxt 應用程式,基於 Iconify

功能 ✨

  • Nuxt 3 準備就緒
  • SSR 友善
  • 透過 Iconify 支援 200,000 個以上的開源向量圖示
  • 支援 CSS 模式 / SVG 模式
  • 自訂 SVG 支援 (透過 Vue 元件,或透過本地 SVG 檔案)

!NOTE 您正在檢視此模組的 v1.0 版本,這是為了更好的開發者體驗和效能而完全重寫的版本。如果您是從 v0.6 遷移而來,請查看 此 PR 以取得完整變更列表。

設定 ⛓️

執行以下命令以將模組新增至您的專案

npx nuxi module add icon

就是這樣,您現在可以在您的元件中使用 <Icon /> 了!

✨ 如果您正在使用 VS Code,您可以使用 Iconify IntelliSense 擴充功能,作者為 @antfu

手動設定

您可以使用以下命令手動安裝模組

npm i -D @nuxt/icon

更新您的 nuxt.config.ts

export default defineNuxtConfig({
  modules: [
    '@nuxt/icon'
  ]
})

如果您已安裝舊版模組 nuxt-icon,您可能需要將其從 modules 列表中移除。

用法 👌

Props

  • name (必填):圖示名稱或全域元件名稱
  • size:圖示大小 (預設:1em)
  • mode:圖示渲染模式 (svgcss,預設:css)

屬性:

當使用來自 Iconify 的圖示時,將會根據渲染模式建立 <span><svg>,您可以給予原生元素的所有屬性

<Icon name="uil:github" style="color: black" />

Iconify 資料集

您可以使用來自 https://icones.js.org 集合的任何名稱

<Icon name="uil:github" />

它支援 i- 前綴 (例如,i-uil-github)。

強烈建議使用以下命令在本地安裝圖示資料

npm i -D @iconify-json/collection-name

例如,若要使用 uil:github 圖示,請使用 @iconify-json/uil 安裝其集合。這樣一來,圖示就可以在本地或從您的無伺服器函式提供服務,這在 SSR 和客戶端都更快且更可靠。

!NOTE 您可能也知道您可以安裝 @iconify/json 套件來包含所有 iconify 圖示。不建議這樣做,因為這會增加您的伺服器捆綁包大小和建置效能。如果您選擇這樣做,我們建議您明確指定您需要的集合名稱

export default defineNuxtConfig({
  modules: ['@nuxt/icon'],
  icon: {
    serverBundle: {
      collections: ['uil', 'mdi'] // <!--- this
    }
  }
})

Vue 元件

name 符合全域註冊的元件時,它將會被渲染為該元件 (在這種情況下 mode 將被忽略)

<Icon name="MyComponent" />

請注意,MyComponent 需要在 components/global/ 資料夾中 (請參閱 範例)。

!TIP 您也可以使用以下命令變更元件名稱

export default defineNuxtConfig({
  icon: {
    componentName: 'NuxtIcon'
  }
})

自訂本地集合

您可以使用本地 SVG 檔案來建立自訂 Iconify 集合。

例如,將您的圖示 SVG 檔案放在您選擇的資料夾下,例如,./assets/my-icons

assets/my-icons
├── foo.svg
├── bar-outline.svg

在您的 nuxt.config.ts 中,在 icon.customCollections 中新增一個項目

export default defineNuxtConfig({
  modules: [
    '@nuxt/icon'
  ],
  icon: {
    customCollections: [
      {
        prefix: 'my-icon',
        dir: './assets/my-icons'
      },
    ],
  },
})

然後您可以像這樣使用圖示

<template>
  <Icon name="my-icon:foo" />
  <Icon name="my-icon:bar-outline" />
</template>

請注意,自訂本地集合需要您擁有伺服器來提供 API。當設定 ssr: false 時,提供者將預設為 Iconify API (其中沒有您的自訂圖示)。如果您想要建置具有伺服器端點的 SPA,您可以明確設定 provider: 'server'

export default defineNuxtConfig({
  modules: [
    '@nuxt/icon'
  ],
  ssr: false,
  icon: {
    provider: 'server', // <-- this
    customCollections: [
      {
        prefix: 'my-icon',
        dir: './assets/my-icons'
      },
    ],
  },
})

區分大小寫的自訂集合

v1.10 之前,由於 Iconify 先前慣例的限制,所有自訂圖示都被正規化為 kebab-case 並帶有警告。感謝 Iconify 方面的更新,從 v1.10 開始,您可以選擇使用區分大小寫的自訂集合並繞過正規化。

export default defineNuxtConfig({
  modules: [
    '@nuxt/icon'
  ],
  icon: {
    customCollections: [
      {
        prefix: 'my-icon',
        dir: './assets/my-icons',
        normalizeIconName: false, // <-- this
      },
    ],
  },
})

這讓您可以使用 assets/my-icons/FooBar.svg 作為 my-icon:FooBar,例如。

normalizeIconName 預設為 true 以實現向後相容性,並且將在未來的主要版本中翻轉。請參閱 #265 以取得更多背景資訊。

圖示自訂

若要更新 <Icon /> 的預設大小 (1em),請使用 icon.size 屬性建立 app.config.ts

使用 icon.class 屬性更新 <Icon /> 的預設類別 (.icon),對於無頭圖示,設定 icon.class: ''`。

您還可以定義別名,以便透過利用 icon.aliases 屬性更輕鬆地替換圖示。

!NOTE 請注意,這是 app.config.ts 而不是 nuxt.config.ts,用於執行階段設定。

// app.config.ts
export default defineAppConfig({
  icon: {
    size: '24px', // default <Icon> size applied
    class: 'icon', // default <Icon> class applied
    mode: 'css', // default <Icon> mode applied
    aliases: {
      'nuxt': 'logos:nuxt-icon',
    }
  }
})

圖示將具有 24px 的預設大小,並且 nuxt 圖示將可用

<Icon name="nuxt" />

預設情況下,此模組將建立伺服器端點 /api/_nuxt_icon/:collection,以從您的本地伺服器捆綁包提供圖示 (您可以透過將 icon.localApiEndpoint 設定為您想要的路徑來覆寫預設路徑)。當請求本地捆綁包中不存在的圖示時,它將回退到請求 官方 Iconify API。您可以透過將 icon.fallbackToApi 設定為 false 來停用回退,或設定 您自己的 Iconify API 並將 icon.iconifyApiEndpoint 更新為您自己的 API 端點。

使用 customize 選項自訂圖示

customize 選項允許您修改專案中使用的 SVG 圖示的各個方面。使用此選項,您可以

  • 變更筆劃寬度
  • 變更顏色
  • 變更動畫持續時間
  • 變更不透明度
  • 新增額外形狀

透過這些自訂選項,您可以完全控制 SVG 內容。

在元件中,您可以在元件中定義 customize 函式,以將各種修改應用於您的圖示。

<script setup lang="ts">
// Define the customize function to modify SVG content
const customize = (content: string, name: string, prefix: string, provider: string) => {
  if (prefix !== 'tabler') return content // Ignore Prefix

  return content
    .replace(/stroke-width="[^"]*"/g, `stroke-width="2"`) // Change stroke width to 2
    .replace(/stroke="[^"]*"/g, `stroke="#FF5733"`) // Change stroke color to red
    .replace(/fill="[^"]*"/g, `fill="#FF5733"`) // Change fill color to red
    .replace(/animation-duration="[^"]*"/g, `animation-duration="1s"`) // Change animation duration to 1s (for animated icons)
    .replace(/opacity="[^"]*"/g, `opacity="0.8"`);// Change opacity to 0.8
}
</script>

<template>
  <Icon name="tabler:star" :customize="customize" />
</template>

在應用程式設定檔中

或者,您可以在 app.config.ts 檔案中全域套用這些自訂設定。

// app.config.ts
export default defineAppConfig({
  icon: {
    customize: (content: string, name: string, prefix: string, provider: string) => {
      // ...
    },
  }
})

透過此設定,您的應用程式中的所有圖示都將一致地套用這些自訂設定。

伺服器捆綁包

@nuxt/icon v1.0 起,我們引入了伺服器捆綁包概念,以從 Nuxt 伺服器端點提供圖示。這使客戶端捆綁包保持精簡,並能夠按需載入圖示,同時具有所有動態功能來使用在建置時可能未知的圖示。

伺服器捆綁包模式:local

此模式會將您在本地安裝的圖示集合 (例如 @iconify-json/*) 捆綁到您的伺服器捆綁包中作為動態區塊。集合資料將按需載入,僅當您的客戶端從該集合請求圖示時才會載入。

伺服器捆綁包模式:remote

@nuxt/icon v1.2 中引入,您現在可以使用 remote 伺服器捆綁包從遠端 CDN 提供圖示。

export default defineNuxtConfig({
  modules: [
    '@nuxt/icon'
  ],
  icon: {
    serverBundle: 'remote',
  },
})

或者您可以指定遠端提供者

export default defineNuxtConfig({
  modules: [
    '@nuxt/icon'
  ],
  icon: {
    serverBundle: {
      remote: 'jsdelivr', // 'unpkg' or 'github-raw', or a custom function
    }
  },
})

這將使伺服器請求 https://cdn.jsdelivr.net/npm/@iconify-json/ph/icons.json 以在執行階段提取圖示,而不是將它們與您的伺服器捆綁在一起。

在底層,它現在會使用類似 () => fetch('https://cdn.jsdelivr.net/npm/@iconify-json/ph/icons.json').then(res => res.json()) 的程式碼,而不是將 () => import('@iconify-json/ph/icons.json') 捆綁到您的伺服器捆綁包中,其中集合不會內聯。

當伺服器捆綁包大小是一個問題時,例如在無伺服器或 worker 環境中,這會很有用。

伺服器捆綁包模式:auto

這是預設選項,模組將根據您的部署環境在 localremote 之間選擇。local 將是首選,除非您要部署到無伺服器或 worker 環境,例如 Vercel Edge 或 Cloudflare Workers。

外部化圖示 JSON

預設情況下,Nitro 會將您在本地安裝的圖示集合 (例如 @iconify-json/*) 捆綁到您的伺服器捆綁包中作為動態區塊。當您有大量圖示時,這可能會使您的捆綁過程變慢且佔用大量記憶體。您可以透過將 icon.serverBundle.externalizeIconsJson 設定為 true 來變更為外部化圖示 JSON 檔案。

export default defineNuxtConfig({
  modules: [
    '@nuxt/icon'
  ],
  icon: {
    serverBundle: {
      externalizeIconsJson: true,
    }
  },
})

請注意,這將要求您的生產 Node.js 伺服器能夠匯入 JSON 檔案 (請注意,如同 Node.js v22 中,JSON 模組仍然是一項實驗性功能)。在最終建置中,它將包含類似 () => import('@iconify-json/ph/icons.json', { with: { type: 'json' } }) 的語句。

另請注意,在某些無伺服器環境中,例如 Cloudflare Workers,它們沒有動態匯入,無論此選項如何,它們始終會內聯。

當啟用 icon.serverBundle.remote 時,將忽略此選項。

完全停用伺服器捆綁包

如果您想要完全停用伺服器捆綁包,您可以將 icon.serverBundle 設定為 false,並將 provider 設定為 iconify

export default defineNuxtConfig({
  modules: [
    '@nuxt/icon'
  ],
  icon: {
    provider: 'iconify',
    serverBundle: false,
  },
})

這將在客戶端每次請求圖示時向 Iconify API 發出請求。除非其他選項不可行,否則我們不建議這樣做。

客戶端捆綁包

對於您知道您將經常使用的圖示,您可以將它們與您的客戶端捆綁包捆綁在一起,以避免網路請求。

export default defineNuxtConfig({
  modules: [
    '@nuxt/icon'
  ],
  icon: {
    clientBundle: {
      // list of icons to include in the client bundle
      icons: [
        'uil:github',
        'logos:vitejs'
      ],

      // scan all components in the project and include icons 
      scan: true,

      // include all custom collections in the client bundle
      includeCustomCollections: true, 

      // guard for uncompressed bundle size, will fail the build if exceeds
      sizeLimitKb: 256,
    },
  },
})

includeCustomCollections 將包含您在 icon.customCollections 中定義的所有自訂集合在客戶端捆綁包中。預設情況下已停用,但在設定 ssr: false 時會自動啟用。

掃描元件

當啟用 scan 時,模組將掃描您專案中的所有元件,並包含客戶端捆綁包中使用的圖示。這將顯著減少靜態已知圖示所需的網路請求數量,但也可能會增加客戶端捆綁包大小,具體取決於您的專案中使用的圖示數量。

您也可以微調掃描目標,例如

export default defineNuxtConfig({
  modules: [
    '@nuxt/icon'
  ],
  icon: {
    clientBundle: {
      scan: {
        // note that when you specify those values, the default behavior will be overridden
        globInclude: ['components/**/*.vue', /* ... */],
        globExclude: ['node_modules', 'dist', /* ... */],
      },
    },
  },
})

!TIP 掃描依賴靜態分析,這表示僅會偵測到文字用法。盡可能避免動態建構圖示名稱。

<template>
  <!-- Avoid this -->
  <Icon :name="`carbon:${dark ? 'moon' : 'sun'}`" />

  <!-- Prefer this -->
  <Icon :name="dark ? 'carbon:moon' : 'carbon:sun'" />
</template>

渲染函式

您可以在渲染函式中使用 Icon 元件 (如果您建立函式元件,這會很有用),為此您可以從 #components 匯入它

import { Icon } from '#components'

請參閱 <MyIcon> 元件的範例

<script setup>
import { Icon } from '#components'

const MyIcon = h(Icon, { name: 'uil:twitter' })
</script>

<template>
  <p><MyIcon /></p>
</template>

貢獻 🙏

  1. Clone 此儲存庫
  2. 使用 pnpm install 安裝依賴項 (使用 corepack enable 安裝 pnpm了解更多)
  3. 執行 npm run dev:prepare 以產生類型存根。
  4. 使用 npm run dev 在開發模式下啟動 playground

致謝 💌

許可證 📎

MIT 許可證